我有引起的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