无法恢复活动:不允许启动服务意图,应用程序在后台。

4

我自己无法重现此崩溃,但是最近在Crashlytics中看到了很多崩溃。该崩溃仅发生在Android 9及更高版本上:

Fatal Exception: java.lang.RuntimeException
    Unable to resume activity {co.whitesmith.flicks/co.whitesmith.flicks.media.audio.AudioPlayerActivity}: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.devbrackets.android.playlistcore.start_service cmp=co.whitesmith.flicks/.media.service.MediaService (has extras) }: app is in background uid UidRecord{63e190 u0a221 TPSL bg:+3h19m42s918ms idle change:idle procs:1 seq(2385,2385,2385)}`

堆栈跟踪:
android.app.ContextImpl.startServiceCommon (ContextImpl.java:1616)
android.app.ContextImpl.startService (ContextImpl.java:1571)
android.content.ContextWrapper.startService (ContextWrapper.java:669)
arrow_right
com.devbrackets.android.playlistcore.manager.BasePlaylistManager.play (BasePlaylistManager.kt:298)
co.whitesmith.flicks.media.audio.AudioPlayerFragment.startPlayback (AudioPlayerFragment.kt:231)
co.whitesmith.flicks.media.audio.AudioPlayerFragment.restartAudio (AudioPlayerFragment.kt:201)
co.whitesmith.flicks.media.audio.AudioPlayerFragment.updateCurrenPlaybackInformation (AudioPlayerFragment.kt:401)
co.whitesmith.flicks.media.audio.AudioPlayerFragment.onResume (AudioPlayerFragment.kt:118)
androidx.fragment.app.Fragment.performResume (Fragment.java:2649)

我不理解这个崩溃。为什么不能在onResume()方法中启动服务?难道不应该在活动进入Resumed状态时处于前台吗?


在播放之前,我调用了super。 - ricardopereira
2个回答

9
这是个bug!在Android 9+中,应用程序UID转为前台和恢复活动之间存在竞争。
这是谷歌提供的解决方法:
问题已在未来的Android版本中得到解决。应用程序可以通过调用ActivityManager.getRunningAppProcesses()在Activity.onResume()中获取进程状态,如果重要性级别低于ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,则避免启动Service。如果设备尚未完全唤醒,活动将立即暂停,并在设备完全唤醒后再次恢复。
然而,有一个更简单的解决方法,即将服务的启动延迟到应用程序完全转为前台。
new Handler().postDelayed(() -> startService(...), 100);

我猜想将启动服务的延迟设置为100毫秒并不能保证应用已完全转入前台。 - ricardopereira
@ricardopereira 你可以安排一个重复的任务并检查进程状态,一直重复任务直到你获得 IMPORTANCE_FOREGROUND - frogatto
有人知道这个问题是否已经被修复,以及是否可以使用吗?否则,有人有一个一直有效的解决方法吗? - rideintothesun
根据我的应用程序崩溃报告,看起来在Android 12+上已经不再是一个问题了。 - levi

4

@frogatto 在代码中所解释的内容:

        //temporary bug fix for https://issuetracker.google.com/issues/110237673
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
        if (runningAppProcesses != null) {
            int importance = runningAppProcesses.get(0).importance;

            if (importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
                //startService(...);
        }

传奇!检查完美无误。 - Starwave

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