我创建了一个基于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,我想:
问题是片段交换逻辑,我想。我如何管理片段交换/切换?
更新
获取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());