2013-11-15 43 views
2

我在onStart()方法中启动了一个AsyncTask,因为我希望它在用户返回该片段时总是从SQLite数据库重新加载数据。这是因为它是一个ListFragment,并且对项目的单击会在平板电脑上的双窗格布局或对列表中的所有项目使用ViewPager的Activity中调出另一个片段。在后一种情况下,我需要重新加载项目,因为用户可以从ViewPager中删除项目。API 8 - AsyncTask 2旋转后出现NullPointerException

现在我正在测试各种设备和API上的布局。

在Froyo(API 8)NexusOne AVD上,如果我旋转屏幕一次,它会再次启动AsyncTask并重新显示数据。如果我再做一次,我会得到一个NullPointerException。当我使用API​​ 10+启动另一个AVD时,我不会发生这种情况(我可以旋转显示所有我想要的)。我花了大量的时间在第二轮之前完成第一轮。

这里是logcat的:

11-14 21:03:46.485: E/AndroidRuntime(326): FATAL EXCEPTION: main 
11-14 21:03:46.485: E/AndroidRuntime(326): java.lang.NullPointerException 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.widget.ArrayAdapter.init(ArrayAdapter.java:271) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:150) 
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$MyAdapter.<init>(MyListFragment.java:279) 
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$getMyAsync.onPostExecute(MyListFragment.java:393) 
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$getMyAsync.onPostExecute(MyListFragment.java:1) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask.finish(AsyncTask.java:417) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask.access$300(AsyncTask.java:127) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.Handler.dispatchMessage(Handler.java:99) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.Looper.loop(Looper.java:123) 
11-14 21:03:46.485: E/AndroidRuntime(326): at android.app.ActivityThread.main(ActivityThread.java:4627) 
11-14 21:03:46.485: E/AndroidRuntime(326): at java.lang.reflect.Method.invokeNative(Native Method) 
11-14 21:03:46.485: E/AndroidRuntime(326): at java.lang.reflect.Method.invoke(Method.java:521) 
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
11-14 21:03:46.485: E/AndroidRuntime(326): at dalvik.system.NativeStart.main(Native Method) 

MyListFragment.java:279是该呼叫到ArrayAdapter .constructor [编辑]

super(context, 0, myListArray); 

onPostExecute(MyListFragment.java:393是这:

mAdapter = new MyAdapter(getActivity(), myListArray); 

上面没有得到exe如果myListArray为null,则cuted。

添加此该指令以上:

if (getActivity() == null) { 
    Log.d(TAG, "getActivity() is null"); 
} 

getActivity()是一个API 8装置上返回null!

这只是Eclipse/ADT和/或AVD测试环境的错误吗?还是会出现在真实的手机上呢?

谢谢。

EDIT

方法来启动的AsyncTask:

@Override 
public void onStart() { 
    super.onStart(); 
    mProgressBarLayout.setVisibility(View.VISIBLE); 
    new getListAsync().execute(mType); 
} 

的的AsyncTask(内私有类的ListFragment的):

private class getListAsync extends AsyncTask<EFFECT_TYPE, Void, List<Item>> { 

    @Override 
    protected List<Item> doInBackground(EFFECT_TYPE... params) { 
     List<Item> items; 
     items = DatabaseManager.get(getActivity()).getItems(params[0]); 
     return items; 
    } 

    @Override 
    protected void onPostExecute(List<Item> result) { 
     super.onPostExecute(result); 
     mProgressBarLayout.setVisibility(View.GONE); 
     mItemList = result; 
     if (mItemList != null) { 
      if (getActivity() == null) { 
       Log.d(TAG, "getActivity() is null"); <---- THIS GETS LOGGED ON THE 2nd ROTATE! 
      } 
393 -----------> mAdapter = new MyAdapter(getActivity(), mItemList); 
      setListAdapter(mAdapter); 
     } 
    } 

} 

EDIT#2

那么,这个 是不可能的。

我已经有onAttach(),所以我这样做:

添加一个新的变量来MyListFragment:

private Activity mParentActivity = null; 

修改onAttach():

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    mCallbacks = (Callbacks) activity; 
    mParentActivity = activity; 
    if (mParentActivity == null) { 
     Log.d(TAG, "onAttach() called with null Activity"); 
    } 
} 

onPostExecute:

@Override 
    protected void onPostExecute(List<Item> result) { 
     super.onPostExecute(result); 
     mProgressBarLayout.setVisibility(View.GONE); 
     mItemList = result; 
     if (mItemList != null) { 
      if (mParentActivity == null) { 
       Log.d(TAG, "mParentActivity is null"); 
      } 
      mAdapter = new MyAdapter(mParentActivity, mItemList); 
      setListAdapter(mAdapter); 
     } 
    } 

} 

mP arentActivity在那里是NULL!即使onAttach()在到达onStart()方法之前使用有效的Activity成功执行。

AsyncTask在API 8上坏了。

+0

你有没有发现什么变量是空的..在你打给超..的? – JoxTraex

+0

是的,背景。请参阅我的帖子的底部。 –

+0

您应该发布更多关于如何/何时尝试使用上下文的代码。 – JoxTraex

回答

0

这是我现在的解决方案。如果有人知道更好的,请发布。

@Override 
public void onStart() { 
    super.onStart(); 
    mProgressBarLayout.setVisibility(View.VISIBLE); 
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) { 
     new getItemsAsync().execute(mType); // Do the AsyncTask for API 10+ 
    } else { 
     // For FROYO only, do the operation on the main thread 
     mItemsList = DatabaseManager.get(mParentActivity).getItems(mType); 
     mProgressBarLayout.setVisibility(View.GONE); 
     if (mItemsList != null) { 
      mAdapter = new MyAdapter(mParentActivity, mItemsList); 
      setListAdapter(mAdapter); 
     } 
    } 
} 

这是有效的。