我有引起的NPE崩溃以下堆栈跟踪:Android活动和片段生命周期问题?
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.daybreak.my.app/com.daybreak.my.app.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ViewSwitcher.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2430)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5456)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:735)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ViewSwitcher.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.daybreak.my.app.TimesFragment.onLocationChange(TimesFragment.java:446)
at com.daybreak.my.app.MainActivity.onLocationChange(MainActivity.java:289)
at com.daybreak.my.app.MainActivity.onCreate(MainActivity.java:112)
at android.app.Activity.performCreate(Activity.java:6302)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2383)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5456)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:735)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
我已经安装的方式我的应用程序如下:
MainActivity
public class MainActivity extends AppCompatActivity implements LocationChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
//...
onLocationChange(LocationManager.getSavedLocation(this)); // Manually calling onLocationChange() method
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) return;
showFragment(new TimesFragment(), TimesFragment.TAG);
}
}
@Override
public void onLocationChange(Locatin location) {
if (location == null) return;
//...
// Call attached onLocationChange() if it implements LocationChangeListener
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (f instanceof LocationChangeListener)
((LocationChangeListener) f).onLocationChange(location);
}
}
TimesFragment
public class TimesFragment extends Fragment implements LocationChangeListener {
private ViewSwitcher viewSwitcher;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//...
viewSwitcher = (ViewSwitcher) view.findViewById(R.id.view_switcher);
}
@Override
public void onLocationChange(Location location) {
this.location = location;
viewSwitcher.setOnClickListener(null); //<-- NPE Cause here
updateContent();
}
}
我的意料 据我了解,在Activity.onCreate()
后,才重新开始或应用程序已被杀害后(由用户明确或内存管理用户返回到应用程序之后被调用时,其他应用需要记忆)。如果发生这种情况,碎片也将被销毁并且需要被创建,即碎片的onCreateView()
将被调用。因此在连接片段之前从MainActivity.onCreate()
调用onLocationChange()
是安全的,因为findFragmentById()
在onLocationChange()
内不会找到任何片段。
REALITY 从堆栈跟踪中我们可以看到从MainActivity.onCreate()
发起的呼叫。但是令我费解的是,当时onLocationChange()
被MainActivity.onCreate()
调用时,onLocationChange()
中的findFragmentById()
在视图容器中找到片段并调用片段onLocationChange()
。发生这种情况时,viewSwitcher
为NULL
,并导致应用程序崩溃。
很明显,片段已经被添加到视图容器中,片段onCreateView()
尚未被调用。
问题
我不能重现此死机了,不知道这是造成这一生命周期的过程。
因此,谁能告诉我
- 如何重现这个错误,
- 生命周期过程中,负责就是造成NPE流量?
FindViewById在某些条件下返回null,是的。我不明白为什么这是一个生命周期问题 –
通过从片段的XML布局中排除'view_switcher',您可以轻松地重现错误 –
@ cricket_007我怀疑我的用户正在编辑片段的XML文件......需要了解它在用户设备上运行时发生。 – fahmy