我的应用需要在后台访问共享首选项文件.自从我开始使用v21支持库的actionbaractivity来保存我的片段后,我的app力就关闭了.每当片段离开屏幕时强制关闭,但异步任务仍在运行并尝试访问该sharedpreferences文件.为什么要抛出这个错误,我该如何解决?
这是堆栈跟踪:
12-22 23:49:49.469: E/AndroidRuntime(23016): FATAL EXCEPTION: AsyncTask #4 12-22 23:49:49.469: E/AndroidRuntime(23016): Process: com.bernard.beaconportal.activities, PID: 23016 12-22 23:49:49.469: E/AndroidRuntime(23016): java.lang.RuntimeException: An error occured while executing doInBackground() 12-22 23:49:49.469: E/AndroidRuntime(23016): at android.os.AsyncTask$3.done(AsyncTask.java:300) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.FutureTask.run(FutureTask.java:242) 12-22 23:49:49.469: E/AndroidRuntime(23016): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.lang.Thread.run(Thread.java:818) 12-22 23:49:49.469: E/AndroidRuntime(23016): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.support.v4.app.FragmentActivity.getSharedPreferences(java.lang.String, int)' on a null object reference 12-22 23:49:49.469: E/AndroidRuntime(23016): at com.bernard.beaconportal.activities.Due_Tommorow_Fragment$Update.doInBackground(Due_Tommorow_Fragment.java:815) 12-22 23:49:49.469: E/AndroidRuntime(23016): at com.bernard.beaconportal.activities.Due_Tommorow_Fragment$Update.doInBackground(Due_Tommorow_Fragment.java:1) 12-22 23:49:49.469: E/AndroidRuntime(23016): at android.os.AsyncTask$2.call(AsyncTask.java:288) 12-22 23:49:49.469: E/AndroidRuntime(23016): at java.util.concurrent.FutureTask.run(FutureTask.java:237) 12-22 23:49:49.469: E/AndroidRuntime(23016): ... 4 more
以下是发生错误的特定代码行:
SharedPreferences userName = getActivity().getSharedPreferences( "Login_Info", Context.MODE_PRIVATE);
这是发生错误的异步任务:
public class Update extends AsyncTask{ private final HttpClient Client = new DefaultHttpClient(); @Override protected Void doInBackground(String... urls) { SharedPreferences bDay = getActivity().getSharedPreferences( "Login_Info", Context.MODE_PRIVATE); String day1 = Integer.toString(bDay.getInt("Day", 0)); String year1 = Integer.toString(bDay.getInt("Year", 0)); String month1 = Integer.toString(1 + bDay.getInt("Month", 0)); SharedPreferences userName = getActivity().getSharedPreferences( "Login_Info", Context.MODE_PRIVATE); String day = day1.replaceFirst("^0+(?!$)", ""); String month = month1.replaceFirst("^0+(?!$)", ""); String year = year1.replaceFirst("^0+(?!$)", ""); String birthday = month + "/" + day + "/" + year; System.out.println("Birthday = " + birthday); String user = userName.getString("username", ""); // String user = (username).split("@")[0]; System.out.println("Username = " + user); try { // HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); // HttpGet httpGet = new HttpGet( // "http://www.beaconschool.org/~markovic/lincoln.php"); HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost( "http://www.beaconschool.org/~markovic/lincoln.php"); try { // Add your data List nameValuePairs = new ArrayList ( 2); nameValuePairs .add(new BasicNameValuePair("username", user)); nameValuePairs.add(new BasicNameValuePair("birthday", birthday)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); // Execute HTTP Post Request response = httpclient.execute(httppost); Log.d("Http Response:", response.toString()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block } catch (IOException e) { // TODO Auto-generated catch block } try { Log.d("receiver", "animation stopped and downloaded file"); String homework = new Scanner(response.getEntity() .getContent(), "UTF-8").useDelimiter("\\A").next(); // String homework = // Html.fromHtml(duetommorow_html).toString(); SharedPreferences.Editor localEditor = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE).edit(); SimpleDateFormat dateFormat = new SimpleDateFormat( "MM/dd hh:mm a"); Calendar cal = Calendar.getInstance(); String downloaded = dateFormat.format(cal.getTime()); localEditor.putString("homework_content", homework); localEditor.putString("download_date", downloaded); localEditor.apply(); localEditor.putString("homework_content", homework); localEditor.apply(); Log.d("receiver", "information given to shared preferences"); due_tommorow_list.clear(); parse_due_tommorow_string(); parse_due_tommorow_content(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (NullPointerException e) { due_tommorow_list.clear(); parse_due_tommorow_string(); parse_due_tommorow_content(); SharedPreferences.Editor localEditor = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE).edit(); localEditor.putString("download_error", "yes"); localEditor.apply(); e.printStackTrace(); } catch (NoSuchElementException e) { due_tommorow_list.clear(); parse_due_tommorow_string(); parse_due_tommorow_content(); SharedPreferences.Editor localEditor = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE).edit(); localEditor.putString("download_error", "yes"); localEditor.apply(); e.printStackTrace(); } catch (RuntimeException e) { due_tommorow_list.clear(); parse_due_tommorow_string(); parse_due_tommorow_content(); SharedPreferences.Editor localEditor = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE).edit(); localEditor.putString("download_error", "yes"); localEditor.apply(); e.printStackTrace(); } } finally { } return null; } @Override protected void onPostExecute(Void result) { swipeLayout.setRefreshing(false); Log.d("sender", "Broadcasting message"); Intent intent = new Intent("up_navigation"); intent.putExtra("message", "This is my message!"); LocalBroadcastManager.getInstance(getActivity()).sendBroadcast( intent); Toast.makeText(getActivity(), "Refresh Finished", 4000).show(); SharedPreferences download_error = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE); String error = download_error.getString("download_error", "no"); String download_date = "Download error, refreshed homework using homework downloaded at " + download_error.getString("download_date", ""); if (error.equals("yes")) { SharedPreferences.Editor localEditor = getActivity() .getSharedPreferences("homework", Context.MODE_PRIVATE) .edit(); Toast.makeText(getActivity(), download_date, Toast.LENGTH_LONG) .show(); localEditor.putString("download_error", "no"); localEditor.commit(); } adapter.notifyDataSetChanged(); swipeLayout.setRefreshing(false); } }
Wesley.. 10
你做了一些耗时的事情AsyncTask
,当getActivity()
部件被执行时,Activity就被销毁了.所以引用getActivity()
返回null,这是非常正确的.
你应该做的是在你的Thread
或者AsyncTask
你应该总是检查是否getActivity()
为null,以防Activity
你的主机Fragment
被销毁.
我不认为@ I'm_With_Stupid的答案是一个很好的实践,因为Activity
在你的Fragment
片段中保留一个参考是不好的,片段已经为你做了.
摆脱这种情况的一种方法是在调用onAttach时保留活动参考,并在需要的地方使用活动参考,例如
@Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; }
现在在您的活动的顶部放置:
private Activity mActivity;
对于每个给您带来问题的SharedPreference,将"getActivity()"替换为"mActivity"
你做了一些耗时的事情AsyncTask
,当getActivity()
部件被执行时,Activity就被销毁了.所以引用getActivity()
返回null,这是非常正确的.
你应该做的是在你的Thread
或者AsyncTask
你应该总是检查是否getActivity()
为null,以防Activity
你的主机Fragment
被销毁.
我不认为@ I'm_With_Stupid的答案是一个很好的实践,因为Activity
在你的Fragment
片段中保留一个参考是不好的,片段已经为你做了.