API 8 - AsyncTask的NullPointerException异常后2转动 [英] API 8 - AsyncTask NullPointerException after 2 rotates

查看:105
本文介绍了API 8 - AsyncTask的NullPointerException异常后2转动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始在调用onStart()方法AsyncTask的,因为我希望它总是从SQLite数据库重装数据,当用户返回到该片段。这是因为它是一个ListFragment,并在项目上点击或带来了在片剂的两面板布局或使用ViewPager对列表中的所有项目的一个活动另一个片段。在后一种情况下,我需要重新加载的物品,因为用户可以删除从ViewPager项

I start an AsyncTask in the onStart() method, because I want it to always reload the data from the SQLite database when the user returns to that Fragment. This is because it is a ListFragment, and a click on an item either brings up another Fragment in a two-pane layout on tablets or an Activity that uses ViewPager for all of the items in the list. In the latter case, I need to reload the items, because the user can delete items from the ViewPager.

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

Now I am testing my layouts on various devices and APIs.

在一个升级Froyo(API 8)NexusOne的AVD,如果我一旦旋转屏幕,它再次启动的AsyncTask并重新显示数据。如果我再这样做,我得到一个NullPointerException异常。当我开始使用API​​ 10+另一个​​AVD不会发生这种情况(我可以旋转所有我想要的显示)。我给它足够的时间做第二个前完成第一旋转。

On a Froyo (API 8) NexusOne AVD, if I rotate the screen once, it starts the AsyncTask again and redisplays the data. If I do it again, I get a NullPointerException. This does not occur when I start another AVD using API 10+ (I can rotate the display all I want). I give it plenty of time to complete the first rotation before doing the second.

下面是LogCat中:

Here is the 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

MyListFragment.java:279 is the call to the ArrayAdapter.constructor

super(context, 0, myListArray);

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

onPostExecute(MyListFragment.java:393 is this:

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

以上没有得到执行,如果myListArray为null。

The above does not get executed if myListArray is null.

我说这该指令上面:

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

getActivity()方法返回null的API 8设备上!

这仅仅是一个使用Eclipse / ADT和/或AVD测试环境中的错误?还是会出现真实的手机吗?

Is this just a bug with the Eclipse/ADT and/or AVD test environment? Or will it occur on real phones too?

感谢。

修改

方法来启动AsyncTask的:

Method to start the AsyncTask:

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

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

The AsyncTask (inner private class of the 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);
        }
    }

}


编辑#2


EDIT #2

好了,这是不可能的。

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

I already have onAttach(), so I did this:

一个新的变量添加到MyListFragment:

Add a new variable to MyListFragment:

private Activity mParentActivity = null;

修改onAttach():

Modified 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:

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);
        }
    }

}

mParentActivity是空在那里!尽管onAttach()与有效的活动成功地执行前,到了在onStart()方法。

mParentActivity is NULL there! Even though onAttach() executed successfully with a valid Activity before it got to the onStart() method.

AsyncTask的被打破的API 8。

AsyncTask is broken on API 8.

推荐答案

下面是我的解决方案现在。如果任何人一个更好的人都知道,请张贴。

Here is my solution for now. If anyone knows of a better one, please post it.

@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);
        }
    }
}

这工作。

这篇关于API 8 - AsyncTask的NullPointerException异常后2转动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆