admin管理员组

文章数量:1403229

I have a messaging app that receives instant messages over a websocket. However there seems to be no reliable way to persist this connection so that the user can receive messages and notifications while the app is closed. I've looked into various options such as the WorkManager and JobScheduler API's, but they don't meet my needs. WorkManager supports coroutines but doesn't have a nice way of restarting it if its killed by the system, and JobScheduler has the onStopJob() method to help with restarts, but has no support for coroutines. I've included my current solution below. I figure this is a common problem for messaging apps so there has to be a supported solution somewhere right?

Manifest:

<receiver
    android:name=".messaging.MessagingService"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="com.rld.datingapp.RESTART_MESSAGING_LISTENER"/>
    </intent-filter>
</receiver>

Receiver:

class MessageStarter: BroadcastReceiver() {
    @RequiresApi(Build.VERSION_CODES.S)
    override fun onReceive(context: Context, intent: Intent) {
        if(intent.action == Intent.ACTION_BOOT_COMPLETED || intent.action == MESSAGING_RESTART_BROADCAST) {
            Log.d(MESSAGING_LOG_TAG, "Starting Service")
            val scheduler = context.getSystemService(JobScheduler::class.java) as JobScheduler
            scheduler.schedule(
                JobInfo.Builder(id++, ComponentName(context.applicationContext, MessagingService::class.java))
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                    .setPersisted(true)
                    .setExpedited(true)
                    .setOverrideDeadline(0)
                    .build()
            )
        } else Log.d(MESSAGING_LOG_TAG, "Received another intent")
    }

    companion object {
        const val MESSAGING_RESTART_BROADCAST = "com.rld.datingapp.RESTART_MESSAGING_LISTENER"
        const val MESSAGING_LOG_TAG = "$LOGGER_TAG Worker 1"
        var id = 0
    }
}

Service:

class MessagingService: JobService() {
    init {
        Configuration.Builder() //stop the warning
            .setJobSchedulerJobIdRange(0, 1000)
            .build()
    }

    override fun onStartJob(params: JobParameters): Boolean {
        Dispatchers.IO.apply {
            dispatch(this) {
                //do our work
            }
        }
        return true
    }

    override fun onStopJob(params: JobParameters): Boolean {
        Log.d(MESSAGING_LOG_TAG, "Restarting Service")
        baseContext.sendBroadcast(Intent(MESSAGING_RESTART_BROADCAST))
        return false //receiver will restart it
    }
}

本文标签: androidI should I persist background work for entire time phone is turned onStack Overflow