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

时间:2020-02-03 11:18:02

标签: android android-activity android-service android-9.0-pie

我自己无法重现此崩溃,但最近在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()方法启动服务? 活动进入恢复状态时不应该在前台吗?

2 个答案:

答案 0 :(得分:2)

这是一个错误!在Android 9+中,在应用程序UID变为前台和活动恢复之间存在竞争。

这是Google的解决方法:

此问题已在以后的Android版本中解决。

有一种解决方法,可以避免应用程序崩溃。应用程序可以通过调用来获取Activity.onResume()中的进程状态 ActivityManager.getRunningAppProcesses()并避免在以下情况下启动服务 重要性等级低于 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND。如果 设备尚未完全唤醒,活动将立即暂停, 最终在完全清醒后再次恢复。

但是,有一种更简单的解决方法可以将服务的启动延迟到应用程序完全变为前台:

new Handler().postDelayed(() -> startService(...), 100);

答案 1 :(得分:1)

@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(...);
        }