首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >API 8-2旋转后的AsyncTask NullPointerException

API 8-2旋转后的AsyncTask NullPointerException
EN

Stack Overflow用户
提问于 2013-11-15 05:28:43
回答 1查看 267关注 0票数 2

我在onStart()方法中启动了一个onStart()方法,因为我希望它总是在用户返回到该片段时从SQLite数据库重新加载数据。这是因为它是一个ListFragment,对一个项目的单击会在平板电脑上的两个窗格布局中显示另一个片段,或者一个对列表中的所有项目使用ViewPager的活动。在后一种情况下,我需要重新加载项目,因为用户可以从ViewPager中删除项。

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

在Froyo (API 8) NexusOne AVD上,如果我旋转屏幕一次,它将再次启动AsyncTask并重新显示数据。如果我再做一次,我会得到一个NullPointerException。当我使用API 10+启动另一个AVD时,就不会发生这种情况(我可以任意旋转显示)。我给它足够的时间来完成第一轮之前进行第二轮。

下面是LogCat:

代码语言:javascript
复制
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)

ArrayAdapter.constructor编辑的调用MyListFragment.java:279

代码语言:javascript
复制
super(context, 0, myListArray);

onPostExecute(MyListFragment.java:393是这样的:

代码语言:javascript
复制
mAdapter = new MyAdapter(getActivity(), myListArray);

如果myListArray为null,则不会执行上述操作。

我在上面加上了这个指令:

代码语言:javascript
复制
if (getActivity() == null) {
    Log.d(TAG, "getActivity() is null");
}

getActivity()在API 8设备上返回null!

这仅仅是Eclipse/ADT和/或AVD测试环境中的一个bug吗?或者它也会发生在真实的手机上?

谢谢。

编辑

方法启动AsyncTask:

代码语言:javascript
复制
@Override
public void onStart() {
    super.onStart();
    mProgressBarLayout.setVisibility(View.VISIBLE);
    new getListAsync().execute(mType);
}

AsyncTask (ListFragment的内部私有类):

代码语言:javascript
复制
    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);
        }
    }

}

编辑#2

这是不可能的。

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

向MyListFragment添加一个新变量:

代码语言:javascript
复制
private Activity mParentActivity = null;

修改后的onAttach():

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@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);
        }
    }

}

mParentActivity在那里是空的!即使onAttach()在到达onStart()方法之前成功地使用有效的活动执行。

AsyncTask在API 8上被破坏了。

EN

回答 1

Stack Overflow用户

发布于 2013-11-15 06:54:09

这是我现在的解决方案。如果有人知道一个更好的,请张贴它。

代码语言:javascript
复制
@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);
        }
    }
}

这个很管用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19994187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档