13

对于极少数用户来说,我正面临一个非常令人困惑的问题。当在 Fragment 内按下按钮时会发生错误,这会启动另一个 Fragment Activity。这是堆栈跟踪:

I/20:22:23.901 ActivityManager( 1668)
Start proc com.brandall.nutter for activity com.brandall.nutter/.ActivityHomeFragment: pid=8956 uid=10125 gids={50125, 3003, 3001, 3002, 1015, 1023, 1006, 1028}
I/20:22:23.881 WindowState( 1668)
WIN DEATH: Window{41ed1948 u0 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment}
W/20:22:23.881 ActivityManager( 1668)
Force removing ActivityRecord{411c4188 u0 com.brandall.nutter/.ActivityLinkAppsFragment}: app died, no saved state
I/20:22:23.881 WindowState( 1668)
WIN DEATH: Window{41b6a178 u0 Toast EXITING}
W/20:22:23.881 InputDispatcher( 1668)
Attempted to unregister already unregistered input channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)'
W/20:22:23.871 ActivityManager( 1668)
Scheduling restart of crashed service com.brandall.nutter/.TTSS in 80000ms
I/20:22:23.871 ActivityManager( 1668)
Process com.brandall.nutter (pid 8907) has died.
I/20:22:23.871 WindowState( 1668)
WIN DEATH: Window{411d4ff0 u0 com.brandall.nutter/com.brandall.nutter.ActivityHomeFragment}
E/20:22:23.871 InputDispatcher( 1668)
channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)' ~ Channel is unrecoverably broken and will be disposed!
W/20:22:23.871 InputDispatcher( 1668)
channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)' ~ Consumer closed input channel or an error occurred.  events=0x9

由于这行错误:

com.brandall.nutter/.ActivityLinkAppsFragment}: app died, no saved state

我一直在阅读许多关于片段保存状态的帖子,但似乎没有一个适用于我的情况,而是适用于片段本身,堆栈跟踪中没有提到。其他帖子建议添加到每个片段:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

我目前没有在我的任何片段中覆盖 onCreate 方法。

我还看到建议将其添加到每个片段中:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    setUserVisibleHint(true);
}

除了只发生在极少数用户身上的事实之外,最令人困惑的问题是使用的上下文:

final Intent sa = new Intent(getActivity(), ActivityLinkAppsFragment.class);
getActivity().startActivity(sa);

我的应用程序有一个前台服务,如果我在上面的 Intent 中使用该服务的静态上下文(通过静态 getServiceContext() 方法),则用户不再出现问题并且片段活动正确打开。

我不明白为什么使用另一个 Context 应该可以防止问题发生,但我希望根据我提供的信息,这对某人有意义!

如果证明相关,我可以提供我正在使用的 FragmentPagerAdapter 代码,但它非常标准。

我提前谢谢你

编辑- 我忘了添加一些非常重要的东西。这不会导致应用程序崩溃。相反,Fragment 所在的 Activity 会立即重新启动。

回答- 这是由于我System.exit(0)在我认为只有当用户想要“刷新”应用程序的内存使用量时才可能调用的情况下造成的。我错了,当用户的设备处理低内存条件时也可以调用它。@beworker 下面的答案被标记为正确,正如他所指出ActivityManagerService.handleAppDiedLocked()的那样。

4

1 回答 1

11

我查看了堆栈跟踪中消息的 Android 源代码,发现它来自ActivityManagerService.handleAppDiedLocked()方法。这种方法的描述说:

“由于该流程消失而从活动管理器中删除现有流程的主要功能。清除与流程的所有连接。”

当应用程序被杀死时会发生这种情况。它可以被系统、另一个应用程序(例如任务管理器应用程序)或当应用程序自己完成时(例如System.exit(0))杀死。

于 2013-08-21T18:55:42.440 回答