在Android API >=24上无法恢复活动,出现java.lang.IllegalArgumentException异常

79

我的应用在运行版本为 7.07.1.18.0.0 的设备上崩溃,以下是堆栈跟踪信息:

Fatal Exception: java.lang.RuntimeException: Unable to resume activity {xxx/xxx.views.activities.HomeActivity}: java.lang.IllegalArgumentException
   at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3788)
   at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2991)
   at android.app.ActivityThread.-wrap14(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6692)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by java.lang.IllegalArgumentException
   at android.os.Parcel.readException(Parcel.java:1697)
   at android.os.Parcel.readException(Parcel.java:1646)
   at android.app.ActivityManagerProxy.isTopOfTask(ActivityManagerNative.java:6600)
   at android.app.Activity.isTopOfTask(Activity.java:6142)
   at android.app.Activity.onResume(Activity.java:1331)
   at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:485)
   at xxx.views.activities.BaseActivity.onResume(BaseActivity.java:50)
   at xxx.views.activities.HomeActivity.onResume(HomeActivity.java:364)
   at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1277)
   at android.app.Activity.performResume(Activity.java:7058)
   at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3765)
   at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2991)
   at android.app.ActivityThread.-wrap14(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6692)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

我在被报告的这些行上的代码非常简单:

// HomeActivity class
@Override
public void onResume() {
    mPresenter.onResume();
    super.onResume();

    renderView();
}

// BaseActivity class
@Override
protected void onResume() {
    super.onResume();
    // some other code
}

我对此进行了一些调查,并找到了类似的问题

由于抛出的IllegalArgumentException没有详细信息,我将尝试按照这里建议的添加额外的日志。

同时,请欣赏任何帮助!


1
在 onResume 方法调用中,应该首先调用 super.onResume。 - JoxTraex
1
@JoxTraex onResume 是 onResume 方法中的第一件事情。但这并不能解决问题。我在我的项目中也遇到了同样的问题。 - Ani
你测试过Android L 5.1.x了吗? - JoxTraex
1
在安卓7和8上也是一样的。你找到解决方案了吗? - Zhanbolat Raimbekov
你的堆栈跟踪还显示:at xxx.views.activities.HomeActivity.onResume(HomeActivity.java:364)。这是自定义的吗?看起来你没有发布你正在使用的所有代码。 - milosmns
1
我有同样的问题,有没有其他解决方案? - Ortensia C.
3个回答

2
            catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                        "Unable to resume activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
                }
            }

这是一个链接异常,所以要检查 e.getCause() 堆栈跟踪 -> 直到原因为空为止。

如果找不到它,请查看调用 try 块的活动线程中的方法:

try {
  r.activity.onStateNotSaved();
  r.activity.mFragments.noteStateNotSaved();

  if (r.pendingIntents != null) {
    deliverNewIntents(r, r.pendingIntents);
    r.pendingIntents = null;
  }

  if (r.pendingResults != null) {
    deliverResults(r, r.pendingResults);
    r.pendingResults = null;
  }

  r.activity.performResume();

  // If there is a pending local relaunch that was requested 
  // when the activity was
  // paused, it will put the activity into paused state
  // when it finally happens.
  // Since the activity resumed before being relaunched, 
  // we don't want that to happen,
  // so we need to clear the request to relaunch paused.

  for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
    final ActivityClientRecord relaunching =
    mRelaunchingActivities.get(i);

    if (relaunching.token == r.token
        && relaunching.onlyLocalRequest &&
        relaunching.startsNotResumed) {
            relaunching.startsNotResumed = false;
    }
 }
}

你需要在以下内容中寻找原因:

  • Activity.onStateNotSaved();
  • Activity.mFragments.noteStateNotSaved();
  • Activity.performResume();
  • 以及 Activity.onNewIntent() 的最终版本
    Caused by java.lang.IllegalArgumentException
        at android.os.Parcel.readException(Parcel.java:1697)
        at android.os.Parcel.readException(Parcel.java:1646)
        at android.app.ActivityManagerProxy.isTopOfTask (ActivityManagerNative.java:6600)
        at android.app.Activity.isTopOfTask(Activity.java:6142)
        at android.app.Activity.onResume(Activity.java:1331)

最好的解决方案是使用 best shot:

startActivity(intent,bundle animantion) 时出现 rjava.lang.IllegalArgumentException 异常


-1

我在我的项目中也遇到了同样的问题。在研究过程中,我发现如果您尝试从Activity的onResume()方法访问任何static变量或方法,这也是可能的。


5
请问您能否解释一下,在onResume()中访问static变量或方法会导致什么问题? - Darshna Desai
1
我明确提到在研究过程中,我找到了解决方案。我还提到,如果您尝试在onResume()方法中访问静态变量,则可能会出现问题。 - Ajay Mehta
3
Voodoo不是答案。 - NateS

-1

问题出在你的包裹上。你需要找到活动、片段、视图保存包裹以保存状态的位置。可能会有错误的顺序,例如:

@Override
protected Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();

    final CharSequence textFromEditText = mTextView.getText();
    if (textFromEditText != null) {
        SavedState savedState = new SavedState(superState);
        savedState.text = textFromEditText.toString();
        return savedState;
    }
    return superState;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (!(state instanceof SavedState)) {
        super.onRestoreInstanceState(state);
        return;
    }

    SavedState savedState = (SavedState) state;
    super.onRestoreInstanceState(savedState.getSuperState());
    if (!TextUtils.isEmpty(savedState.text)) {
        mTextView.setText(savedState.text);
    }
}

private static class SavedState extends BaseSavedState {
    String text;

    private SavedState(Parcelable superState) {
        super(superState);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeString(text);
    }

    private SavedState(Parcel source) {
        super(source);
        text = source.readString();
    }

    public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {

        @Override
        public SavedState createFromParcel(Parcel source) {
            return new SavedState(source);
        }

        @Override
        public SavedState[] newArray(int size) {
            return new SavedState[size];
        }
    };
}

所以问题可能出在某个地方

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeString(text);
    }

    private SavedState(Parcel source) {
        super(source);
        text = source.readString();
    }

当包裹来源读取的顺序不正确时。


问题出在 onResume 上,而不是 onRestoreInstanceState。 - Pnemonic
我有类似的问题,你知道其他的解决方案吗? - Ortensia C.
什么样的问题? - Vytautas Berankis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接