Android - Service、IntentService、JobIntentService - 如果应用程序被杀死,它们将停止

8

我在StackOverflow和Web上看到了很多相同的问题,但是无法配置类似于“永不停止的服务”或者即使应用程序被从任务中删除(强制杀死)也可以运行。我想知道像Viber或WhatsUp这样的服务是如何工作的,因为当我们强制关闭这些应用程序时,仍然能够接收到有人写信给我们的消息(因此服务仍在运行)。我知道前台服务,但这并不是解决方案,因为用户不想看到通知。所以这里是我尝试过的:这段代码在服务内部运行以检测实时更改,并希望它在应用的每个条件下保持活动状态:前台、后台、已删除等。

firestoreDb!!.collection("example").document("example").collection("real_time_request")
                    .addSnapshotListener { documentSnapshot: QuerySnapshot?, _: FirebaseFirestoreException? ->

                    }

我是这样使用服务从Firestore数据库获取实时数据的,当用户集合中有更改时,我会得到通知。
我尝试过以下几种方式:
FirestoreListeners : IntentService("Firestore Listeners")
FirestoreListeners : Service
FirestoreListeners : JobIntentService

当应用程序在前台或后台运行时,以上所有内容都正常工作,但是当应用程序被强制关闭(从任务中删除)时,服务将被终止。

我尝试在清单中进行以下更改:

android:stopWithTask="false"
android:directBootAware="true"
android:process=":remote"

在应用程序层级中:
android:persistent="true"

在IntentService的onHandleIntent方法中:
setIntentRedelivery(true)

在 onStartCommand 服务中:

return START_STICKY

如果系统销毁或杀死服务,尝试重新启动服务:

override fun onTaskRemoved(rootIntent: Intent) {
        val restartServiceIntent = Intent(applicationContext, this::class.java)
        restartServiceIntent.setPackage(packageName)
        val restartServicePendingIntent = PendingIntent.getService(applicationContext, 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT)
        val alarmService = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent)
        Log.e("Service Firestore ", "Task Removed")
        super.onTaskRemoved(rootIntent)
    }

但是没有任何一个方案可以正常运行。 怎样能实现监听Firestore更改(或其他内容)的后台服务,即使应用程序已被杀死或从任务中删除,类似于Viber等应用程序...也许他们正在使用前台服务而没有通知图标?但我认为Android不允许我们创建这种前台服务(没有通知)。
我已经阅读了一些关于WorkManager的文章,正如Google所说:
注意: WorkManager适用于需要保证系统即使在应用退出时也会运行它们的任务,例如将应用数据上传到服务器。 它不适用于可以安全终止的进程内后台工作,如果应用程序进程消失,则建议使用ThreadPools处理此类情况。
但我无法弄清楚它如何工作或如何用于我的目的。
谢谢

你尝试过Google的codelab吗?https://codelabs.developers.google.com/codelabs/android-workmanager/#0 - Raghav Satyadev
请查看以下解决方案:https://dev59.com/71UL5IYBdhLWcg3wV2uq#50639788 - Abdul Aziz
4个回答

3

当你的应用程序处于未运行/前台状态时,你可以使用FCM推送通知来唤醒设备。当应用程序接收到推送通知时,你可以启动服务执行所需任务。但是当应用程序在后台时,你可能无法启动服务,因此你可能需要将服务作为前台服务运行。


嗨,谢谢您的想法。是的,您对这个解决办法是正确的,但我不认为Viber或其他应用程序使用类似于此解决办法唤醒设备。 - EAK TEAM
那么不使用 FCM 的服务呢? - EAK TEAM
我相信WhatsApp/Viber应该正在使用FCM。现在大多数通话应用程序都在使用FCM。 - Ramesh Yankati
@EAKTEAM,除了基础知识以外,我对Android编程并不熟悉,但你是否考虑过可能根本无法实现你想要的功能呢?实际上,我希望这是不可能的,因为运行一个可以在强制停止后继续运行且不显示任何通知的后台任务(如果我理解得正确的话)似乎会带来安全问题。 - 11684
@11684 我明白。但是为什么谷歌自己不像 FCM 一样实现一个专门用于此目的的服务呢?哈哈,我知道你无法回答这个问题,只是随口问问。 - EAK TEAM
显示剩余2条评论

2
WorkManager现在是在后台执行某些工作的最佳解决方案。因为现在Android操作系统对于长时间运行后台任务的允许性更加严格。根据官方文档... WorkManager会选择适当的方式来安排后台任务--取决于设备API级别和包含的依赖项,WorkManager可能使用JobScheduler、Firebase JobDispatcher或AlarmManager。
Android开发者网站是学习WorkManager的好地方https://developer.android.com/topic/libraries/architecture/workmanager/basics
对于一个连续运行并间隔一段时间的周期性任务,您可以创建一个PeriodicWorkRequest并将其排队到WorkManager实例中。 https://developer.android.com/topic/libraries/architecture/workmanager/basics#recurring 另一种较旧的方法是只使用AlarmManager。这样,您不必一直在后台运行服务。您可以设置一个重复的闹钟,当它触发时,您可以启动一个服务并进行需要的操作。

0
在 Android 的 Doze 模式文档中,他们特别指明了 FirebaseJobDispatcher 的使用,这将即使在 Doze 模式下也能正常工作,但每 15 分钟只会执行一次。你可以使用 Android 架构组件中的 WorkManager,它可以适当地使用 FirebaseJobDispatcher、AlarmManager 和 JobScheduler ,在相应的支持 API 级别上使用。

0

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