当用户在凌空异步操作期间使用NavigationDrawer更改片段时,应用程序崩溃

时间:2015-03-24 22:39:46

标签: android android-fragments asynchronous android-volley

我创建了一个基于Android Studio导航抽屉模板的应用程序。

我有3个片段,每个片段实现各种Vollye异步网络请求。

问题是: 当一个用户在片段A上播放时,会触发一个发送凌空异步网络请求的动作,并且在获得结果和UI更新之前,它会切换到片段B,显然应用程序会引发NULL指针异常。

基本上,片段A的异步网络请求的回调无法更新UI,因为片段A被片段B替换为具有完全不同的UI元素,片段A上下文被破坏。

所以,我认为问题是片段交换/切换的逻辑。

这是我的MainActivity" onNavigationDrawerItemSelected "每次用户点击NavigationDrawer元素时调用的方法:

@Override
public void onNavigationDrawerItemSelected(int position)
{
    // update the main content by replacing fragments
    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment frag = null;

    switch (position)
    {
        case 0: // A
            frag = FragmentA.newInstance(position + 1);
            break;
        case 1: // B
            frag = FragmentB.newInstance(position + 1);
            break;
        case 2: // C
            frag = FragmentC.newInstance(position + 1);
            break;
        default:
    }

    if (frag != null)
    {
        fragmentManager.beginTransaction()
                .replace(R.id.container, frag)
                .commit();
    }
}

现在问题很明显,每当用户点击NavigationDrawer的元素时,所选片段就会膨胀到布局中,替换(销毁)旧片段。

解决此问题的最佳方法是什么?

用户可以在每个时刻切换片段,我不想禁用等待特定异步网络请求结束的UI,并且imho清除Volley队列以停止在onPause()/期间触发异步请求onDestroy()方法不是一个好的解决方案..它不是解决方案。

如果用户点击片段B,我想:

  • 检查是否存在片段A的Volley排队请求 - >清除它们。
  • 如果有任何请求被触发且系统正在等待响应,请获取 响应(当它到来时)并在有或没有更新UI的情况下处理它。

问题是片段交换逻辑,我想。我如何管理片段交换/切换?

更新

获取sharedPreferences对象时出错的示例:

FATAL EXCEPTION: main
Process: ***************, PID: 21174
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference

导致NULLpE的代码。 FragmentA的Volley异步请求中的回调(在FragmentA中定义并执行),在响应到来时(在用户切换到片段B之后)调用,执行以下操作:

[...]
// we are inside FragmentA
// Volley Async Network Request callback code
APILibrary lib = new APILibrary(getActivity());
[...]

这是APILibrary构造函数方法:

public APILibrary(Context context) {
  this.fooObject = new FooObject(context)
}

这是FooObject构造函数方法,其中发生了FATAL EXCEPTION:

public FooObject(Context context) {
    mContext =  context;
    mSharedPrefs = mContext.getSharedPreferences(MYFOOTAG, mContext.MODE_PRIVATE);
}

致命错误的另一个例子

E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.foo.bar, PID: 20676
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
        at android.view.ViewConfiguration.get(ViewConfiguration.java:359)
        at android.view.View.<init>(View.java:3580)
        at android.view.View.<init>(View.java:3675)
        at android.view.ViewGroup.<init>(ViewGroup.java:491)
        at android.widget.LinearLayout.<init>(LinearLayout.java:200)
        at android.widget.LinearLayout.<init>(LinearLayout.java:196)
        at android.widget.LinearLayout.<init>(LinearLayout.java:192)
        at android.widget.LinearLayout.<init>(LinearLayout.java:188)
        at android.widget.TableRow.<init>(TableRow.java:61)
        at com.foo.bar.FragmentA.initTable(FragmentA.java:879)
        at com.foo.bar.FragmentA.parseData(FragmentA.java:681)
        at com.foo.bar.FragmentA$7.update(FragmentA.java:436)
        at com.foo.bar.CustomAPI$1.onResponse(CustomAPI.java:283)
        at com.foo.bar.CustomAPI$1.onResponse(CustomAPI.java:280)
        at com.foo.bar.CustomRequest.deliverResponse(CustomRequest.java:83)
        at com.foo.bar.CustomRequest.deliverResponse(CustomRequest.java:22)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

在FragmentA上运行异步任务时,用户切换到另一个片段后,生成Null Pointer Exception的代码为:

at com.foo.bar.FragmentA.initTable(FragmentA.java:879):
TableRow headrow = new TableRow(getActivity());

0 个答案:

没有答案