首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Android 10中启动活动时崩溃

在Android 10中启动活动时崩溃
EN

Stack Overflow用户
提问于 2019-10-04 16:40:28
回答 1查看 4.8K关注 1票数 10

在Android 10 (SDK 29)上运行我的应用程序(最小SDK 21)时,我遇到了一个问题。

该应用程序的初始活动如预期的那样出现并显示。现在,当按下按钮调出顶部的第二个活动时,我看到了这个崩溃日志:

代码语言:javascript
复制
java.lang.IllegalStateException: Activity top position already set to onTop=false
    at android.app.ActivityThread.handleTopResumedActivityChanged(ActivityThread.java:4370)
    at android.app.servertransaction.TopResumedActivityChangeItem.execute(TopResumedActivityChangeItem.java:39)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

第二个活动是在SDK 29以下的所有Android版本上正常启动。代码非常简单,如下所示

代码语言:javascript
复制
    this.startActivity (new Intent (MyFirstActivity.this, MySecondActivity.class));

有什么可能触发这个问题的提示吗?异常(“活动顶部位置已经设置为onTop=false")实际上告诉了我什么?

为了方便起见,下面是ActivityThread.java代码:

代码语言:javascript
复制
@Override
public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r == null || r.activity == null) {
        Slog.w(TAG, "Not found target activity to report position change for token: " + token);
        return;
    }
    if (DEBUG_ORDER) {
        Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
    }
    if (r.isTopResumedActivity == onTop) {
        throw new IllegalStateException("Activity top position already set to onTop=" + onTop);
    }
    r.isTopResumedActivity = onTop;
    if (r.getLifecycleState() == ON_RESUME) {
        reportTopResumedActivityChanged(r, onTop, "topStateChangedWhenResumed");
    } else {
        if (DEBUG_ORDER) {
            Slog.d(TAG, "Won't deliver top position change in state=" + r.getLifecycleState());
        }
    }
}

以下是AndroidManifest的摘录:

代码语言:javascript
复制
<application
    ...

    <activity
        android:name="com.xxx.MyFirstActivity"
        android:label="@string/${applicationLabel}"
        android:launchMode="singleTask" 
        android:configChanges="orientation|keyboardHidden|screenSize" >

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity>

    ...

    <activity
        android:name="com.xxx.MySecondActivity"
        android:label="@string/ls_Quick_Reference"
        android:icon="@drawable/action_help"  >
    </activity>

    ...

</application>
EN

回答 1

Stack Overflow用户

发布于 2019-12-17 22:37:48

我在这里回答我自己的问题。我已经在Google的/Android的跟踪工具中提交了一个bug,并与作者进行了平行联系。

https://issuetracker.google.com/issues/140571893

总而言之,我的部分代码搞砸了Android的活动堆栈,崩溃是由此导致的延迟结果。

详细地说:当启动我的应用程序时,有时有必要运行一些迁移或修复以前运行的操作。由于这些操作需要在主线程上完成,并且我想通知用户他/她需要等待一段时间,因此我引发了一个显示消息的视图。由于我的应用程序正忙于处理主线程,显示并未刷新,视图也不可见。为了解决这个问题,我运行了一个“内部循环”来允许分派显示消息:

代码语言:javascript
复制
try
{
    //  At this point all draw events should be in the event queue,
    //  now add another event to the end of queue to finish the loop once everything is processed.
    Handler handler = new Handler (Looper.myLooper());

    handler.postDelayed (new Runnable() {
        @Override
        public void run() {
            throw new FinishLoopRunTimeException();
        }
    }, 50);

    Looper.loop();
}
catch (FinishLoopRunTimeException e) {}

FinishLoopRunTimeException是RuntimeException的简单特化。

虽然这是一种有效的刷新显示消息的方法,但在Android10中,当活动状态改变时,Looper.loop ()不能运行。对于我的应用程序,情况就是这样,因为当此代码运行时,主活动已经在启动过程中。如果您这样做,activity线程状态将会崩溃,另一个活动的后续启动将崩溃。

因此,解决方案是在Android 10执行内部循环时确保活动处于稳定状态。较早的Android版本没有显示此问题。

虽然这可以被认为是Android 10的错误(不得在Looper文档中更改提及活动状态),并且应该在未来的版本中修复以使其更加健壮,但可以通过重新使用Looper代码来解决此问题。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58232799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档