Android 停止前台服务执行onStartCommand

Android stop foreground service executes onStartCommand

为什么调用 context.stopService(stopIntent) 会执行 onStartCommand 我错过了什么吗? 我必须在 onStartCommand

中执行此操作
if (ACTION_STOP_SERVICE == intent?.action) { stopSelf() }

虽然文档具体说明了这一点:

onStartCommand Called by the system every time a client explicitly starts the service by calling Context.startService

代码示例

@AndroidEntryPoint
class MyService : Service() {

    private val ACTION_STOP_SERVICE: String = "ACTION_STOP_SERVICE"
    private val ACTION_START_SERVICE: String = "ACTION_START_SERVICE"

    @OptIn(InternalCoroutinesApi::class)
    @ExperimentalCoroutinesApi
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        if (ACTION_START_SERVICE == intent?.action) {
            // Start mqtt client "org.eclipse.paho:org.eclipse.paho.client"
        }

        if (ACTION_STOP_SERVICE == intent?.action) {
            mqtt.disconnect()
            stopSelf()
        }        
        val stopIntent = Intent(this.applicationContext, BPSMqttService::class.java)
        stopIntent.action = ACTION_STOP_SERVICE

        val pStopIntent =
            PendingIntent.getService(
                BPSApp.instance.applicationContext,
                0,
                stopIntent,
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
            )
        val notificationIntent =
            Intent(this.applicationContext, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this.applicationContext,
            0, notificationIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        val notification =
            NotificationCompat.Builder(this.applicationContext, SERVICE_CHANNEL_ID)
                .setContentTitle("My service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_alarms_sync)
                .setContentIntent(pendingIntent)
                .addAction(0, "Stop", pStopIntent)
                .build()
        startForeground(1, notification)
        return START_STICKY
    }

    override fun onDestroy() {
        try {
            super.onDestroy()
            Log.d("MyService ", "onDestroy is done")
        } catch (ex: Throwable) {
            Log.d("MyService ", "onDestroy ${ex.message}")
        }
    }

    override fun onCreate() {
        try {
            super.onCreate()
            Log.d("MyService ", "nCreate is done")
        } catch (ex: Throwable) {
            Log.d("MyService ", "onCreate ${ex.message}")
        }
    }
    
    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

在通知以外的其他地方,我这样做是为了停止

val stopIntent = Intent(BPSApp.instance.applicationContext, BPSMqttService::class.java)
stopIntent.action = "ACTION_STOP_SERVICE"
BPSApp.instance.applicationContext.stopService(stopIntent)

然后这样做开始

val startIntent = Intent(BPSApp.instance.applicationContext, BPSMqttService::class.java)
startIntent.action = "ACTION_START_SERVICE"
BPSApp.instance.applicationContext.startForegroundService(startIntent);

您似乎看到 onStartCommand() 由于您的 Notification 而被调用。

通知操作“停止”将调用 startService(),这就是您所看到的。在代码的其他地方,当你调用stopService()时,onStartCommand()不会被调用。