1 回答

TA貢獻1786條經驗 獲得超11個贊
如果您主動關閉應用程序(通過從 Android 活動列表中關閉它),Android 很可能會終止您的服務。您可以在您的應用程序 Logcat 中看到這一點。唯一真正的解決方法是前臺服務。
此外,onBind不會在每次綁定到服務時調用。從Android 文檔:
您可以同時將多個客戶端連接到一個服務。但是,系統緩存了IBinder服務通信通道。換句話說,只有在第一個客戶端綁定時,系統才會調用服務的 onBind() 方法來生成 IBinder。然后系統將相同的 IBinder 傳遞給綁定到相同服務的所有其他客戶端,而無需再次調用 onBind()。
其次,僅調用 onStartCommand 并不意味著重新創建服務。在服務生命周期內可以多次調用。例如,每次調用 startService 時,都會執行 onStartCommand,但不一定要重新創建服務。
此外,您似乎在關閉活動時沒有取消綁定服務。這會使您的活動泄漏 ServiceConnection 并且您的應用程序崩潰。它將解釋為什么每次關閉并重新啟動應用程序時都會看到重新創建的服務。
嘗試在您的活動的 onPause 方法中添加取消綁定:
@Override
void onPause() {
super.onPause()
unbindService(this.serviceConnectino)
}
工作配置可能如下所示。它使用專用服務函數而不是 onBind 來實現計數器的遞增:
我的綁定服務.kt
package com.test
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log
class MyBoundService : Service() {
abstract class MyBinder: Binder() {
abstract fun getService(): MyBoundService
}
val iBinder: MyBinder = object: MyBinder() {
override fun getService(): MyBoundService {
return this@MyBoundService
}
}
private var counter = 0
fun increment() {
counter ++
Log.i("MyBoundService", "Counter: ${counter}")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i("MyBoundService", "startCommand");
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(p0: Intent?): IBinder? {
counter++
Log.i("MyBoundService", "Bound: ${counter}")
return iBinder
}
override fun onUnbind(intent: Intent?): Boolean {
Log.i("MyBoundService", "Unbound")
return super.onUnbind(intent)
}
}
MainActivity.kt
package com.test
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.ComponentName
import android.content.Context
import android.content.ServiceConnection
import android.os.IBinder
import android.util.Log
import com.test.MyBoundService
class MainActivity : AppCompatActivity() {
private val serviceConnection: ServiceConnection = object: ServiceConnection {
override fun onServiceDisconnected(p0: ComponentName?) {
Log.i("MainActivity", "Service disconnected")
}
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
Log.i("MainActivity", "Service connected")
p1?.let {
(p1 as MyBoundService.MyBinder).getService().increment()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_create.setOnClickListener {
val i = Intent(this@MainActivity, MyBoundService::class.java)
startService(i)
}
btn_bind.setOnClickListener {
val i = Intent(this@MainActivity, MyBoundService::class.java)
bindService(i, serviceConnection, Context.BIND_AUTO_CREATE)
}
}
override fun onPause() {
super.onPause()
unbindService(serviceConnection)
}
}
添加回答
舉報