文章中大部分内容《第一行代码》- 第三版中都有写到,这篇是对文中 Service 以及自己理解的总结。
Service 启动方式
- startService
- bindService
startService
1.创建 Service
class MyService : Service() {
val TAG = "MyService"
override fun onCreate() {
super.onCreate()
Log.d(TAG, "onCreate")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy")
}
override fun onBind(p0: Intent?): IBinder? {
TODO("Not yet implemented")
}
}
暂时不看 onBind 方法,我们重写 onCreate、onStartCommand、onDestroy 方法
2.启动 Service
class ServiceTestActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_service)
btn_start_service.setOnClickListener {
val intent = Intent(this, MyService::class.java)
startService(intent)
}
btn_stop_service.setOnClickListener {
val intent = Intent(this, MyService::class.java)
stopService(intent)
}
}
}
第一次调用 startService,Service 会执行 onCreate 和 onStartCommand 方法。当 Service 创建后,调用 startService 只会执行 onStartCommand 方法。
执行 stopService 会执行 onDestroy 方法。
bindService
- 接下来我们就使用到了 onBind 方法,简单改造下
class MyService : Service() {
private val TAG = "MyService"
private val myBinder = MyBinder()
override fun onCreate() {
super.onCreate()
Log.d(TAG, "onCreate")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy")
}
override fun onBind(p0: Intent?): IBinder? {
Log.d(TAG, "onBind")
return myBinder
}
override fun onUnbind(intent: Intent?): Boolean {
Log.d(TAG, "onUnbind")
return super.onUnbind(intent)
}
class MyBinder : Binder() {
fun todoSomething() {
Log.d("MyBinder", "getData")
}
}
}
第一次调用 bindService,Service 会执行 onCreate 和 onBind 方法,也会执行 Binder 中的 todoSomething 方法。
执行 unbindService 会执行 onUnbind 方法和 onDestroy 方法。
Srevise 生命周期总结
- startService 启动一次
onCreate -> onStartCommand
- startService 启动多次
onCreate -> onStartCommand -> onStartCommand ->...
- stopService
onDestroy
- bindService
onCreate -> onBind
- unbindService
onUnbind -> onDestroy
- startService + bindService
onCreate -> onStartCommand -> onBind
- unbindService + stopService
onUnbind -> onDestroy
startService 和 stopService 对应,bindService 和 unbindService 对应。如果 startService 和 bindService 混合使用,要销毁 Service 就必须同时调用 stopService 和 unbindService 方法。
前台 Service
class MyService : Service() {
...
override fun onCreate() {
super.onCreate()
Log.d(TAG, "onCreate")
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(
"my_service",
"service",
NotificationManager.IMPORTANCE_DEFAULT
)
manager.createNotificationChannel(channel)
}
val intent = Intent(this, TestActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, intent, 0)
val notification = NotificationCompat.Builder(this, "my_service")
.setContentTitle("my_service")
.setContentText("my_service test")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_round))
.setAutoCancel(true)//点击时,通知会自动取消
.setContentIntent(pi)
.build()
startForeground(1, notification)
}
...
}
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
模拟器前台服务
前台服务可以理解成 Service + NotificationManager,通过 startForeground 方法让 Service 变成前台服务。
IntentService
class MyIntentService : IntentService("MyIntentService") {
override fun onHandleIntent(p0: Intent?) {
Log.d("MyIntentService", "onHandleIntent")
}
override fun onDestroy() {
super.onDestroy()
Log.d("MyIntentService", "onDestroy")
}
}
<service
android:name=".kotlin_10.MyIntentService"
android:enabled="true"
android:exported="true" />
MyIntentService 允许完成后会自动调用 onDestroy 方法。
Service 运行在主线程中,如果有耗时操作容易 ANR,所以 Service 中有耗时操作时可以使用 IntentService。
ANR : 主线程 5s、BroadcastReceiver 10s、Service 20s。具体文章可以参考 Android ANR分析详解
网友评论