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

Posted

技术标签:

【中文标题】无法恢复活动:不允许启动服务 Intent,应用程序在后台【英文标题】:Unable to resume activity: not allowed to start service Intent, app is in background 【发布时间】:2020-05-19 03:29:07 【问题描述】:

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

【问题讨论】:

播放前我调用了super。 【参考方案1】:

这是一个错误!在 Android 9+ 中,应用 UID 转到前台和正在恢复的 Activity 之间存在竞争。

这是来自 Google 的解决方法:

该问题已在未来的 Android 版本中得到解决。

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

但是,有一个更简单的解决方法可以延迟服务的启动,直到应用完全转为前台:

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

【讨论】:

我猜延迟启动服务100ms并不能保证应用完全转前台 @ricardopereira 你可以安排一个重复的任务并检查进程状态,重复这个任务直到你得到IMPORTANCE_FOREGROUND 有谁知道这是否已修复,是否可以使用。否则,是否有人对此有一致的解决方法?【参考方案2】:

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

【讨论】:

以上是关于无法恢复活动:不允许启动服务 Intent,应用程序在后台的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.SecurityException-不允许启动活动 Intent flg=0x4000000 cmp=[MY_ACTIVITY] (has extras)

前台服务不启动活动

活动在 startActivity(intent) 后没有启动

未经许可不允许启动服务 Intent X Y

FCM 致命异常:java.lang.IllegalStateException 不允许启动服务 Intent

未经许可不允许启动服务Intent android.permission.BIND_JOB_SERVICE