【发布时间】:2014-02-03 23:49:51
【问题描述】:
我有一个非常不寻常的崩溃,可能每月左右发生一次。似乎没有任何押韵或理由。这是一个大型项目的一部分,由于我不确定问题到底出在哪里,所以我不确定要在此处粘贴哪些代码部分。因此,我将只描述我在做什么,我认为可能是导致崩溃的原因。
我有一个包含许多嵌套片段的活动,我使用 FragmentManager 管理这些片段。因为嵌套的片段可以是相同的类型,所以我必须给每个片段的根视图一个唯一的 ID。该应用程序在调用 super.onResume 时崩溃,该调用是我重载的 onResume 函数的第一行(因此我的代码永远不会有机会搞砸任何事情)。我认为它由于唯一片段 ID 而崩溃的原因是因为我在移动到唯一 ID 后开始遇到这个问题,并且崩溃总是引用低编号的资源 ID。
这个错误似乎是在框架本身中抛出的,所以我不确定我能做些什么。有没有其他人遇到过这个问题,并找到了解决方案?或者,有谁知道你是否可以用 try/catch 块包围 super.onResume ?我不确定应用程序是否能够在那时恢复,而且似乎没有任何方法可以始终如一地重现此错误以对其进行测试。
01-24 20:55:09.602 E/AndroidRuntime( 8156): FATAL EXCEPTION: main
01-24 20:55:09.602 E/AndroidRuntime( 8156): java.lang.RuntimeException: Unable to resume activity {github.daneren2005.dsub/github.daneren2005.dsub.activity.SubsonicFragmentActivity}: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x2
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3014)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3055)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.access$600(ActivityThread.java:151)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.os.Looper.loop(Looper.java:155)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.main(ActivityThread.java:5454)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at java.lang.reflect.Method.invokeNative(Native Method)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at java.lang.reflect.Method.invoke(Method.java:511)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at dalvik.system.NativeStart.main(Native Method)
01-24 20:55:09.602 E/AndroidRuntime( 8156): Caused by: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x2
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.content.res.Resources.getResourceName(Resources.java:1666)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:445)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at github.daneren2005.dsub.activity.SubsonicActivity.onResume(SubsonicActivity.java:130)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at github.daneren2005.dsub.activity.SubsonicFragmentActivity.onResume(SubsonicFragmentActivity.java:250)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1266)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.Activity.performResume(Activity.java:5148)
01-24 20:55:09.602 E/AndroidRuntime( 8156): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2997)
01-24 20:55:09.602 E/AndroidRuntime( 8156): ... 12 more
01-24 20:55:09.602 W/ActivityManager( 596): Force finishing activity github.daneren2005.dsub/.activity.SubsonicFragmentActivity
编辑:添加了唯一 ID 生成。在 onCreateView 我使用 rootView.setId(rootId):
public SelectDirectoryFragment() {
super();
rootId = getNewId();
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
if(bundle != null) {
int tmp = bundle.getInt(Constants.FRAGMENT_ID, -1);
if(tmp > 0) {
rootId = tmp;
}
entries = (List<MusicDirectory.Entry>) bundle.getSerializable(Constants.FRAGMENT_LIST);
restoredInstance = true;
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(Constants.FRAGMENT_ID, rootId);
outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) entries);
}
protected int getNewId() {
for (;;) {
final int result = nextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
if (nextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
}
【问题讨论】: