Android:片段堆栈和被破坏的活动在onResume之后导致空指针异常

时间:2014-08-15 06:33:53

标签: java android exception android-activity android-nested-fragment

我有一个包含2个片段的活动,以及一个内部片段或嵌套片段。

创建活动和片段的流程:

活动 - >片段1 - >片段2 +嵌套片段

    创建活动时,
  • 片段1 会添加到布局中
  • 片段1 按下按钮时,会创建
  • 片段2
  • 片段1 替换为片段2
  • 创建片段2 时,嵌套片段(SupportMapFragment)会自动添加到片段2

我正在尝试模拟: android kill paused-activity (如果系统需要-e.g,当没有更多内存时,android系统可以杀死暂停的活动 - )。

我是怎么做到的?我按下主页按钮,然后从DDMS(eclipse)按下STOP方法。在此之后,我将从android-device菜单重新启动应用程序。

  • 注1:我在片段2 +支持地图片段
  • 注2:SupportMapFragment通过getChildFragmentManager()附加到父片段(片段2)。

如果我这样做(按下主页按钮然后我从DDMS销毁应用程序),我会一直得到这个例外:

08-15 06:11:14.127: E/AndroidRuntime(3205): FATAL EXCEPTION: main
08-15 06:11:14.127: E/AndroidRuntime(3205): Process: com.zbarcea.forks, PID: 3205
08-15 06:11:14.127: E/AndroidRuntime(3205): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zbarcea.forks/com.zbarcea.forks.activities.ActivityMain}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.zbarcea.forks.fragments.FragmentMapMode$4: make sure class name exists, is public, and has an empty constructor that is public
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.os.Looper.loop(Looper.java:136)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread.main(ActivityThread.java:5017)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at java.lang.reflect.Method.invokeNative(Native Method)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at java.lang.reflect.Method.invoke(Method.java:515)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at dalvik.system.NativeStart.main(Native Method)
08-15 06:11:14.127: E/AndroidRuntime(3205): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.zbarcea.forks.fragments.FragmentMapMode$4: make sure class name exists, is public, and has an empty constructor that is public
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.Fragment.instantiate(Fragment.java:413)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1790)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.Fragment.performCreate(Fragment.java:1489)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:893)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1879)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:215)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at com.zbarcea.forks.activities.BaseSlidingMenuFragmentActivity.onCreate(BaseSlidingMenuFragmentActivity.java:93)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at com.zbarcea.forks.activities.ActivityMain.onCreate(ActivityMain.java:205)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.Activity.performCreate(Activity.java:5231)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
08-15 06:11:14.127: E/AndroidRuntime(3205):     ... 11 more
08-15 06:11:14.127: E/AndroidRuntime(3205): Caused by: java.lang.InstantiationException: can't instantiate class com.zbarcea.forks.fragments.FragmentMapMode$4; no empty constructor
08-15 06:11:14.127: E/AndroidRuntime(3205):     at java.lang.Class.newInstanceImpl(Native Method)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at java.lang.Class.newInstance(Class.java:1208)
08-15 06:11:14.127: E/AndroidRuntime(3205):     at android.support.v4.app.Fragment.instantiate(Fragment.java:402)
08-15 06:11:14.127: E/AndroidRuntime(3205):     ... 24 more

所以,每次父片段(片段2 )正在调用SupportMapFragment

时,我都尝试删除onPause().
    @Override
    public void onPause()
    {
        super.onPause();

        infoWindowAdapterMapMode = null;

        getChildFragmentManager().beginTransaction().remove(supportMapFragment).commit();

        supportMapFragment = null;
    }

问题解决了!如果我销毁活动并且我正在恢复应用程序,则会重新创建片段,并且没有例外!

在创建支持地图片段之前,当我按下主页按钮(不是从DDMS调用STOP)时,问题就出现了。

我得到了这个例外:

08-15 06:24:50.679: E/AndroidRuntime(3275): FATAL EXCEPTION: main
08-15 06:24:50.679: E/AndroidRuntime(3275): Process: com.zbarcea.forks, PID: 3275
08-15 06:24:50.679: E/AndroidRuntime(3275): java.lang.NullPointerException
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:651)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.os.Handler.handleCallback(Handler.java:733)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.os.Looper.loop(Looper.java:136)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at android.app.ActivityThread.main(ActivityThread.java:5017)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at java.lang.reflect.Method.invokeNative(Native Method)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at java.lang.reflect.Method.invoke(Method.java:515)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-15 06:24:50.679: E/AndroidRuntime(3275):     at dalvik.system.NativeStart.main(Native Method)

就是这样。我无法识别异常的来源,因为它在支持库中的某处崩溃。

1 个答案:

答案 0 :(得分:0)

首先:我喜欢你专注于清洁和正确处理你的应用程序的方法。非常好!但是,正如你所说:Android可以杀死活动并管理自己的生命周期。操作系统可能会尽快释放为您的活动分配的内存,要求您再次分配。这意味着您的片段可能会或可能不会被销毁。正如您在堆栈跟踪中看到的那样,将调用FragmentActivity.onCreate。 这显然表明您在旧活动的上下文中创建的现有资源不再可访问。通过应用程序生命周期保证存在的唯一上下文是应用程序上下文。对于所有其他资源,您应该了解并正确处理创建的资源在您尝试访问它们时可能无效。