长时间不活动后无法创建新的Loader

时间:2012-10-31 09:05:05

标签: java android android-fragments android-loadermanager android-loader

我有一个Android应用程序,其Fragment依赖于加载程序来获取数据。以下是我Fragment的框架代码。除了我在onLoadFinished方法中有一些自定义代码外,一切都是一样的。

public class Events extends Fragment implements LoaderCallbacks<ArrayList<Event>> {    
    private Integer intWeek;

    public static Events newInstance(Integer intWeek) {    
        Events pageFragment = new Events();
        pageFragment.intWeek = intWeek;
        pageFragment.setArguments(new Bundle());
        return pageFragment;    
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.events, null);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLoaderManager().initLoader(this.intWeek, savedInstanceState, this);
    }

    public Loader<ArrayList<Event>> onCreateLoader(int intLoader, Bundle bndBundle) {
        return new Scraper(getActivity().getApplicationContext());
    }

    public void onLoadFinished(Loader<ArrayList<Event>> ldrEvents, final ArrayList<Event> lstEvents) {    
        //Do something with the returned data
    }

    public void onLoaderReset(Loader<ArrayList<Event>> ldrEvents) {
        return;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }    
}

FragmentFragmentActivity内使用,ViewPager使用Fragment´s using a获取其Fragment FragmentPagerAdapter`。

这很好用,我可以在Fragment之间进行寻呼,就像上面显示的那样。每次向ViewPager添加新的onCreate时,Loader方法都会触发,并会创建新的onCreate

当我按下手机上的“主页”按钮时,应用程序会暂停并进入后台。我可以随时恢复应用程序,它可以正常运行 - 在5/10/20分钟后处于后台。

...但是如果我将应用程序在后台停留很长时间,一小时或更长时间,应用程序在启动时崩溃,堆栈跟踪指向 getLoaderManager().initLoader(this.intWeek, savedInstanceState, this); 方法中的以下行:

initLoader

现在我很遗憾为什么会这样。似乎Android框架在后台长时间不活动后会在后台销毁某些内容,而Loader方法无法创建Transmitting stack trace: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mridang.stadi/com.mridang.stadi.Main}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2079) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2104) at android.app.ActivityThread.access$600(ActivityThread.java:132) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1157) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4575) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.mridang.stadi.events.Events.onCreate(Events.java:73) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:834) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1805) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:200) at com.mridang.stadi.Main.onCreate(Main.java:23) at android.app.Activity.performCreate(Activity.java:4465) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2033) ... 11 more documentation about the initLoader method具体说:

  

确保加载程序已初始化并处于活动状态。如果装载机没有   已经存在,一个被创建并且(如果活动/片段是   目前已启动)启动加载程序。否则最后创建   装载机被重复使用。

有人能够指出我在这里做错了什么吗?这似乎是一个非常难以调试的问题,因为我无法随意复制它。这是非常随机的。感谢


来自logcat的Stacktrace:

{{1}}

2 个答案:

答案 0 :(得分:1)

我遇到了与装载机类似的问题。我发现Fragment / Loader生命周期很复杂。我很想找到一份详细解释它的文件。

无论如何,我为解决问题所做的是将initLoader()调用移至onActivityCreated()方法。试一试。

答案 1 :(得分:0)

尝试使用以下内容:

boolean canFire = ((loader != null) && !loader.isReset());
            // restart or initialise loader
            if (canFire) {
                getLoaderManager().restartLoader(loaderId, args, this);
            } else {
                getLoaderManager().initLoader(loaderId, args, this);
            }