Android 在前台服务中丢失 websocket 连接

Posted

技术标签:

【中文标题】Android 在前台服务中丢失 websocket 连接【英文标题】:Android losing websocket connection in foreground service 【发布时间】:2021-03-21 18:16:21 【问题描述】:

我正在使用与我的服务器的 websocket 连接来接收/发送特定消息。 这些消息还带有通知。

建立连接后一切正常。当我从服务器向应用程序发送消息并且一切正常时,推送通知就会出现,但是当我在 30 分钟或更长时间后再次尝试并从服务器向应用程序发送消息时,什么也没有发生。 从我在日志中可以看到,应用程序和服务器套接字连接都没有断开:/ .

发生这种情况有什么原因吗?

我是否必须每分钟 ping 一次服务器以保持连接正常运行?

这是我用来启动服务的代码。

主活动

...
    override fun onCreate(savedInstanceState: Bundle?) 
            super.onCreate(savedInstanceState)
            val myServiceIntent = Intent(this, ForegroundSocket::class.java)
            ContextCompat.startForegroundService(this, myServiceIntent)
    
...

前台套接字

...
    // Binder given to clients (notice class declaration below)
    private var notification: Notification? = null
    private val mBinder: MyBinder = MyBinder()

    // Channel ID for notification
    val CHANNEL_ID = "Random number notification"

    /**
     * Class used for the client Binder. The Binder object is responsible for returning an instance
     * of "MyService" to the client.
     */
    inner class MyBinder : Binder() 
        // Return this instance of MyService so clients can call public methods
        val service: ForegroundSocket
            get() =// Return this instance of MyService so clients can call public methods
                this@ForegroundSocket
    

    /**
     * This is how the client gets the IBinder object from the service. It's retrieve by the "ServiceConnection"
     * which you'll see later.
     */
    override fun onBind(intent: Intent): IBinder? 
        return mBinder
    

    /**
     * Called when service is created So  we will do our work here
     */
    override fun onCreate() 
        super.onCreate()
        Log.d("MyBoundService", "onCreate called")
        startNotification()
    

    /**
     * Used for creating and starting notification
     * whenever we start our Bound service
     */
    private fun startNotification() 
        val channel = NotificationChannel(
            CHANNEL_ID,
            "My Channel",
            NotificationManager.IMPORTANCE_DEFAULT
        )

        (getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
            channel
        )
        notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_lock_outline)
            .setTicker("Ticker text")
            .setContentTitle("A service is running in the background")
            .setContentText("Generating random number")
            .build()
        startForeground(1, notification)
    


...

【问题讨论】:

【参考方案1】:

我不知道 Binder 基类从何而来,但是 websocket 实现应该提供 onClose

override fun onClose(code: Int, reason: String?, remote: Boolean) 
    Log.d(TAG, "onClose")
    unsubscribe()

如果 onClose 是意外的(没有被客户端关闭),那么你应该尝试重新连接。

【讨论】:

【参考方案2】:

这样你使用绑定服务和入站服务,当活动被销毁时,服务也被销毁。 因此,通过在绑定时返回 null 来无限制这些服务。

【讨论】:

请更具体地说明 OP 可以采取哪些措施来解决他们的问题。

以上是关于Android 在前台服务中丢失 websocket 连接的主要内容,如果未能解决你的问题,请参考以下文章

2019-06-12 关于微服务大数字精度丢失解决方案

android前台服务以及通知

当我在 Android 设置中手动禁用位置时,为啥 Android 前台服务会停止?

带有按钮的 Android 前台服务通知

如何在科尔多瓦运行android前台服务?

与前台服务android通信