gpt4 book ai didi

firebase - 由于后台执行限制,FirebaseMessagingService在Android O上崩溃

转载 作者:行者123 更新时间:2023-12-03 13:29:19 27 4
gpt4 key购买 nike

由于新的后台执行限制,我们的应用在Android O上崩溃了。我们使用的是Firebase版本10.2.1,该版本添加了对Android O的支持。

好像是Firebase的问题?还是需要一些更改来支持我们这一点?

java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.firebase.INSTANCE_ID_EVENT pkg=my.package.name cmp=my.package.name/my.package.name.MyFcmIdService (has extras) }: app is in background uid UidRecord{30558fa u0a327 RCVR idle procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)
at android.app.ContextImpl.startService(ContextImpl.java:1461)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at android.support.v4.content.WakefulBroadcastReceiver.startWakefulService(WakefulBroadcastReceiver.java:99)
at com.google.firebase.iid.zzg.b(zzg.java:9)
at com.google.firebase.iid.zzg.a(zzg.java:72)
at com.google.firebase.iid.zzg.a(zzg.java:2)
at com.google.firebase.iid.FirebaseInstanceIdService.a(FirebaseInstanceIdService.java:23)
at com.google.firebase.iid.FirebaseInstanceIdService.a(FirebaseInstanceIdService.java:34)
at com.google.firebase.iid.FirebaseInstanceId.<init>(FirebaseInstanceId.java:31)
at com.google.firebase.iid.FirebaseInstanceId.getInstance(FirebaseInstanceId.java:47)
at com.google.firebase.iid.FirebaseInstanceId.a(FirebaseInstanceId.java:4)
at com.google.firebase.iid.FirebaseInstanceIdService.a(FirebaseInstanceIdService.java:19)
at com.google.firebase.iid.FirebaseInstanceIdService.b(FirebaseInstanceIdService.java:35)
at com.google.firebase.iid.zzb$zza$1.run(zzb.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)


更新升级到11.4.2解决了此问题。

最佳答案

@KaMyLL是正确的。我的应用程序存在相同的问题,可以通过用JobIntentService替换IntentService(我们在onTokenRefresh()中开始)来解决它。

因为我发现JobSchedulerJobIntentService文档有些混乱,所以我想用一些代码片段来介绍所有内容。我希望这对遇到此问题的每个人都清楚。

是什么导致此问题?

由于Android 8的新版Background Execution Limits,当应用程序可能在后台运行时,您不应再启动后台服务:


当应用程序处于前台时,它可以自由创建和运行前台和后台服务。当应用进入后台时,它会显示几分钟的窗口,在该窗口中仍允许其创建和使用服务。在该窗口结束时,该应用程序被认为是空闲的。这时,系统停止应用程序的后台服务,就像该应用程序已调用服务的Service.stopSelf()方法一样。


并且:


在许多情况下,您的应用程序可以用JobScheduler作业替换后台服务。


因此,对于Android 7.x及更低版本,(据我所知)在后台运行应用程序时使用startService()是没有问题的。但是在Android 8中,这会导致崩溃。因此,您现在应该使用JobSchedulerJobSchedulerIntentService在行为上的区别是IntentService立即执行。另一方面,不能保证排队到JobScheduler的作业立即执行。 Android OS将确定何时有适当的时间这样做,以提高能源效率。因此可能会有延迟。到目前为止,我还不知道需要多长时间。
因此,一种解决方案是检查操作系统版本并使用if-else分支代码。幸运的是,支持库可以帮助我们以更优雅的方式解决此问题,而无需复制任何代码:JobIntentService,这基本上是在后台为您完成的。

如何重现该问题?

上面的第一句引述指出,该应用程序“仍具有几分钟的窗口,仍可在其中创建和使用服务。”,以便重现和调试问题(以Firebase中的onTokenRefresh()为例) ,您可以在使用startService()启动服务之前设置一个断点。关闭应用程序,然后在那里等待5-10分钟。继续执行,您将在此问题中看到IllegalStateException
能够将问题重现为基础,以确保我们的修复程序能够真正解决问题。

如何将我的IntenService迁移到JobIntentService?

我以FirebaseInstanceIdService.onTokenRefresh()为例:

a)将BIND_JOB_SERVICE权限添加到您的服务中:

<service android:name=".fcm.FcmRegistrationJobIntentService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"/>


b)不是从 IntentService扩展,而是从 android.support.v4.app.JobIntentService扩展,将 onHandleIntent(Intent)方法重命名为 onHandleWork(Intent),并添加enqueueWork(Context,Intent)便捷函数:

public class FcmRegistrationJobIntentService extends JobIntentService 
{
// Unique job ID for this service.
static final int JOB_ID = 42;

// Convenience method for enqueuing work in to this service.
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, FcmRegistrationJobIntentService.class, JOB_ID, work);
}

@Override
protected void onHandleWork(@NonNull Intent intent) {
// the code from IntentService.onHandleIntent() ...
}
}


c)使用 enqueueWork()便捷功能开始作业:

public class ComfyFirebaseInstanceIdService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
Intent intent = new Intent(this, FcmRegistrationJobIntentService.class);
// startService(intent);
FcmRegistrationJobIntentService.enqueueWork(this, intent);
}
}


我希望这个例子对您有所帮助。至少按照以下步骤操作后,我再也无法在Android 8设备上重现该问题,并且它仍然可以在我的Android 7设备上运行。

更新资料

由于不建议使用 FirebaseInstanceIdService,我们应该将其从代码中删除,而应使用 FirebaseMessagingService中的 onNewToken

关于firebase - 由于后台执行限制,FirebaseMessagingService在Android O上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46117554/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com