在Android Pie上启动context.startService(intent)

6

我在我的Activity的onResume方法中启动了一个服务,它在Oreo上运行良好,但最近在Android P上出现了崩溃,错误信息为“无法恢复Activity...不允许启动服务意图...应用程序在后台中..”。有人遇到过这种情况并能够修复吗?任何建议都将不胜感激。

@Override
public void onResume() {
    super.onResume();
    Timber.v("onResume");
    Intent intent = new Intent(context, Token.class);
    intent.setAction(ACTION_FETCH_TOKEN);
    context.startService(intent);
}

仅仅为了补充更多的背景信息,我自己无法重现这个崩溃。


2
包含您的代码。 - JediBurrell
这是一段非常简单的代码。 - Mohammed Abdul Bari
protected void onResume() { super.onResume(); context.startService(intent); } - Mohammed Abdul Bari
编辑您的问题以包含代码。intent 在哪里声明的? - JediBurrell
请看这个问题和第一个答案:https://dev59.com/ZKrka4cB1Zd3GeqPjc5C - Javi Mollá
2个回答

1
在Oreo8+上,如果您的应用程序没有“显示”,则无法启动后台服务,为此,您需要像下面这样编辑您的代码:
    protected void onResume() {
        super.onResume(); context.startForegroundService(intent);
 } 

在您的服务类的onCreate()方法中,您还需要添加以下内容:
PendingIntent pIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), 0);
Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("My App")
                .setContentText("Doing some work...")
                .setContentIntent(pIntent).build();
startForeground(1000, notification);

1
是的,但我不想显示通知,有趣的是我不明白为什么在onResume时,应用程序仍然在后台运行,这根本没有意义。 - Mohammed Abdul Bari
1
@MohammedAbdulBari,Post Oreo。没有背景概念。但是你可以在前台运行它。你必须使用context.startForegroundService(intent);,就像Legion所说的那样。现在,如果你要启动一个前台服务,那么你必须在onCreate方法中创建一个通知,并在onCreate的末尾使用startForeground(111, mBuilder.build());来启动你的onStartCommand。这些都是无法推卸的规则..!! 如果你不想要通知,那就意味着你不能在Oreo之后启动服务。就是这样。 - sandhya sasane
1
@sandhyasasane,问题是我没有在后台启动服务,它是在Activity的onResume中启动的一次性服务,这意味着应用程序应该已经在前台,但由于某种原因它并没有。此外,在我的Android 9像素上,应用程序不会崩溃。 - Mohammed Abdul Bari
@MohammedAbdulBari 你有没有找到任何关于为什么在Activity.onResume()中的应用程序不处于前台状态的好解释?并且无论如何这个解决方案对你起作用了吗?顺便说一句,我在Pixel 3 (9.0)上看到了这个问题。 - Mark
不是真的,我现在使用OneTimeWorkRequest而不是使用服务。有趣的是,当我们在Activity.postResume()中启动服务时,我们看到了相同的崩溃。 - Mohammed Abdul Bari
显示剩余5条评论

0

我遇到了同样的问题,这是一个小服务,我不想将其更改为前台服务。然后我发现了谷歌提供的在 onResume 中启动服务的解决方法:

ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
    if (runningAppProcesses != null) {
        int importance = runningAppProcesses.get(0).importance;
        // higher importance has lower number (?)
        if (importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            //start your service the same way you did before in here
            startService(serviceIntent);
        }
    }

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

好的,很高兴知道。你能分享一下来源吗? - Mohammed Abdul Bari

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