kotlin 如何让套接字io在后台工作android

ca1c2owp  于 2022-11-16  发布在  Kotlin
关注(0)|答案(1)|浏览(135)

我有套接字IO连接到一个android应用程序,它通过后台服务接收事件。虽然这是工作正常时,应用程序在前台。当我关闭应用程序或当应用程序进入后台,我已经确认套接字连接,但我无法接收事件时,应用程序在后台。
这是我的服务

const val SOCKET_EVENT = "message:response"

@AndroidEntryPoint
class MService : LifecycleService() {

    @Inject
    lateinit var ioSocket: Socket

    override fun onCreate() {
        super.onCreate()
        ioSocket.connect()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)
        ioSocket.connect()
        AndroidRemoteDebugger.Log.d("Starting  My Service")
        listenToSocketsEvents()
        return START_STICKY
    }

    private fun listenToSocketsEvents() {
        ioSocket.on(SOCKET_EVENT, onSocketEvent)
    }

    private val onSocketEvent: Emitter.Listener = object : Emitter.Listener {
        override fun call(vararg args: Any?) {
            try {
                val data = args[0] as JSONObject
                //While the main thing about the service is that I'm logging data jhere when I get an 
                // incoming socket event it does log when app is in foreground but when it's in 
                // background it doesn't log
                AndroidRemoteDebugger.Log.v(data.toString())
                val message = data.getJSONObject("message")
                val id = message.getString("id")

                playSound()

                val topic = "message-request"
                val intent = Intent(
                    this@MService,
                    MessageReceiver::class.java
                ).apply {
                    putExtra("messageId", id)
                    putExtra("topic", topic)
                }
                sendBroadcast(intent)
            } catch (e: JSONException) {
                AndroidRemoteDebugger.Log.e(e.message)
                return
            }
        }
    }

    private fun playSound() {
        val notificationSound: Uri =
            Uri.parse(
                (ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                        packageName) + "/" + R.raw.car_horn
            )
        val ringtone: Ringtone = RingtoneManager.getRingtone(
            applicationContext,
            notificationSound
        )
        ringtone.play()
    }
}

这是我的接收器

class MessageReceiver: BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        val topic = intent?.getStringExtra("topic")
        val tripId = intent?.getStringExtra("tripId")
        val intent = Intent(Constants.NOTIFICATION).apply {
            putExtra("Notify", topic)
            putExtra("tripId", tripId)
            putExtra("from", Constants.SOCKETS)
        }
        if (context != null) {
            LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
        }

    }
}

虽然该服务的主要功能是在收到传入套接字事件时记录一些内容,但当应用程序处于前台时,它会记录,而当它处于后台时,它不会记录

nnvyjq4y

nnvyjq4y1#

LifecycleService将在应用进入后台时被终止/终止。您应该使用ForegroundService来运行任何后台任务。
来自官方doc
应用在前台时,可以自由创建和运行前台和后台服务;应用进入后台后,有几分钟的时间窗口,可以创建和使用服务;窗口结束时,应用被认为是空闲的,此时系统会停止应用的后台服务。就好像应用程序调用了服务的Service.stopSelf()方法一样。
您的套接字仍然处于连接状态,因为在服务被终止时您没有断开套接字连接。请始终在完成服务后断开套接字连接,以避免不必要的资源消耗。

相关问题