Fabric告诉我一些我无法解释的NPE事件。它们发生在不同的设备和Android版本上。
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{lelisoft.com.lelimath/lelisoft.com.lelimath.activities.CalcActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2328)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
at android.app.ActivityThread.access$900(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5476)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by java.lang.NullPointerException
at lelisoft.com.lelimath.fragment.CalcFragment.setupPlay(CalcFragment.java:253)
at lelisoft.com.lelimath.fragment.CalcFragment.onActivityCreated(CalcFragment.java:86)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2089)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1133)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1272)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2149)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:600)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at lelisoft.com.lelimath.activities.LeliBaseActivity.onStart(LeliBaseActivity.java:94)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1177)
at android.app.Activity.performStart(Activity.java:5461)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
at android.app.ActivityThread.access$900(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5476)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
现在,Activity的源代码始终初始化GameLogic实例并将其传递给onCreate()中的片段:
public class CalcActivity .. {
GameLogic gameLogic;
protected void onCreate(Bundle state) {
setContentView(R.layout.act_calc);
setGameLogic(new CalcLogicImpl());
calcFragment = new CalcFragment();
calcFragment.setLogic((CalcLogic) gameLogic);
initializeCalcFragment(false);
}
private void initializeCalcFragment(boolean replace) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (replace) {
transaction.replace(R.id.calc_content, calcFragment);
} else {
transaction.add(R.id.calc_content, calcFragment);
}
transaction.commit();
}
public void setGameLogic(GameLogic gameLogic) {
this.gameLogic = gameLogic;
}
然后有一个CalcFragment:
public class CalcFragment extends LeliBaseFragment {
CalcLogic logic;
public void setLogic(CalcLogic logic) {
this.logic = logic;
}
public void onActivityCreated(Bundle state) {
setupPlay();
}
这里NPE失败了:
private void setupPlay() {
formulas = logic.generateFormulas();
}
流程清晰,没有其他属性分配。创建活动,实例化和设置属性,创建片段并传递属性。然后片段在onActivityCreated
中初始化,但有时属性为null。它适用于我所有的真实设备和虚拟设备。我不知道为什么它们在那些报告的设备上是空的。
答案 0 :(得分:3)
Android框架通常需要重新实例化片段,以便处理配置更改。您的CalcLogic
等实例状态已丢失。
修复它的一些选项:
从片段logic
或其他类似的早期生命周期方法中的活动中提取onCreate()
字段的值。
调用setRetainInstance(true)
使片段实例在某些通常会发生重新安装的情况下生效。