android学习笔记 - service(kotlin实现)
Posted 我叫白小飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android学习笔记 - service(kotlin实现)相关的知识,希望对你有一定的参考价值。
#service从入门到放弃
微信公众号:没有
如果你觉得此文章对你有帮助,欢迎点赞
###service简介
service和activity 、contentProvider、BroadcastReceiver并称为android四大组件,其地位不言而喻,在使用中也确实举足轻重。service的直接翻译为服务,它是一种在后台执行长时间运行才最而没有UI的应用组件。service可以理解为没有界面的activity,非常适合用于执行不需要交互界面且长期后台运行的任务。service不能运行在独立的进程中,需要依赖创建服务时所在的应用程序进程。服务器不会自动开启工作线程,它和activity一样,创建之后会创建一个主线程,工作线程需要我们手动创建服务可由其他应用组件启动(如Activity),启动方式后边详细讲。
service基本上分为两种状态:
启动状态:
如果一个service是通过startService() 方式启动的,服务当前的状态即为“启动”状态。一旦启动,服务即可在后台长期运行,急事启动该服务的组件已经被销毁,也无任何影响,因为服务此时不依赖任何组件,是独立运行的,除非手动调用停止或者强行停止运行应用才能停止服务,已启动的服务通常是执行单一操作,而且不会把结果返回给调用方。
绑定状态:
如果一个service是通过bindService() 方式启动的,则该服务是“绑定”状态。绑定的服务提供了 客户端-服务端的接口,允许组件与服务器进行交互、发送请求和获取数据,并且可以利用IPC(进程通信机制)进行跨进程执行这些操作。此服务生命周期与绑定该服务的组件一致,组件销毁后绑定的服务也会停止运行。
service创建及使用(启动状态)
- 1.定义一个service:
步骤如下:
- 创建一个类集成自android.app.Service,实现抽象方法onBind(),重写onCreate()、onStart()()、onCommand()、onDestry();
注意
- 在AndroidManifest.xml清单文件中注册该service;
具体实现:(使用kotlin语言实现)
- service代码:
class BookService : Service()
val TAG = "BookService"
override fun onBind(intent: Intent): IBinder?
LogUtils.i(TAG,"onBind")
return null
override fun onCreate()
super.onCreate()
LogUtils.i(TAG,"onCreate")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
LogUtils.i(TAG,"onStartCommand")
return super.onStartCommand(intent, flags, startId)
override fun onDestroy()
super.onDestroy()
LogUtils.i(TAG,"onDestroy")
- AndroidManifest.xml 文件中注册:
<service android:name=".services.BookService"/>
- activity中的代码:
private val TAG = "MainActivity"
val RECEIVE_MESSAGE_CODE : Int = 0x0002
//客户端的消息处理
class ClientHndler : Handler()
override fun handleMessage(msg: Message?)
super.handleMessage(msg)
LogUtils.i(TAG,"clientHndler")
when (msg?.what)
RECEIVE_MESSAGE_CODE ->
LogUtils.i(TAG,"这是来自服务端的问候:" + msg.obj)
else ->
LogUtils.i(TAG,"未接收到服务端的问候!!!")
//初始化客户端的messenger
val clientMessenger = Messenger(ClientHndler())
class MainActivity : AppCompatActivity(),ServiceConnection
override fun onServiceDisconnected(p0: ComponentName?)
//TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
LogUtils.i(TAG,"onServiceDisconnected")
private lateinit var movieService: MovieService
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?)
//TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
LogUtils.i(TAG,"onServiceConnected")
var movieBinder = p1 as MovieService.MovieBinder
movieService = movieBinder.getMovieService()
class Conn : ServiceConnection
val TAG = "Conn"
override fun onServiceDisconnected(p0: ComponentName?)
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
LogUtils.i(TAG,"onServiceDisconnected")
lateinit var serviceMessenger: Messenger
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?)
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
LogUtils.i(TAG,"onServiceConnected")
serviceMessenger = Messenger(p1)
val conn = Conn()
private var bookbinders = Intent()
private var movieBinders = Intent()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
LogUtils.i(TAG,"onCreate")
//直接启动service
btn_start.setOnClickListener
bookbinders.setClass(this,BookService().javaClass)
startService(bookbinders)
//停止service
btn_stop.setOnClickListener
stopService(bookbinders)
//绑定service
btn_bind.setOnClickListener
movieBinders.setClass(this,MovieService::class.java)
bindService(movieBinders,this,Service.BIND_AUTO_CREATE)
//解除绑定
btn_unbind.setOnClickListener
unbindService(this)
//获取数据
btn_getdata.setOnClickListener
val count = movieService.movieName
println("从service获取的count===$count")
//msg bind
btn_msg_bind.setOnClickListener
var intent = Intent()
intent.setClass(this@MainActivity,MusicService::class.java)
bindService(intent,conn,Service.BIND_AUTO_CREATE)
//给service发送消息
btn_send_msg.setOnClickListener
val message = Message.obtain(null, SEND_MESSAGE_CODE, 0, 0)
message.obj = "来自客户端的问候!!!"
message.replyTo = clientMessenger
conn.serviceMessenger.send(message)
//取消绑定
btn_msg_unbind.setOnClickListener
unbindService(conn)
override fun onStart()
super.onStart()
LogUtils.i(TAG,"onStart")
override fun onRestart()
super.onRestart()
LogUtils.i(TAG,"onRestart")
override fun onResume()
super.onResume()
LogUtils.i(TAG,"onResume")
override fun onPause()
super.onPause()
LogUtils.i(TAG,"onPause")
override fun onDestroy()
super.onDestroy()
LogUtils.i(TAG,"onDestroy")
- 界面布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="@string/main_start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.16"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn_bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="@string/main_bind"
app:layout_constraintBottom_toTopOf="@+id/btn_start"
app:layout_constraintEnd_toEndOf="@+id/btn_start"
app:layout_constraintStart_toStartOf="@+id/btn_start" />
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="@string/main_stop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.053"
app:layout_constraintStart_toEndOf="@+id/btn_start" />
<Button
android:id="@+id/btn_unbind"
android:layout_width="103dp"
android:layout_height="47dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="@string/main_unbind"
app:layout_constraintBottom_toTopOf="@+id/btn_stop"
app:layout_constraintEnd_toStartOf="@+id/btn_getdata"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/btn_stop" />
<Button
android:id="@+id/btn_getdata"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="获取数据"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_stop"
app:layout_constraintTop_toTopOf="@+id/btn_bind"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="@+id/btn_msg_bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="112dp"
android:text="绑定service(msg)"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="16dp" />
<Button
android:id="@+id/btn_msg_unbind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="取消绑定service(msg)"
app:layout_constraintBottom_toTopOf="@+id/btn_msg_bind"
tools:layout_editor_absoluteX="16dp" />
<Button
android:id="@+id/btn_send_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="发消息给service"
app:layout_constraintBottom_toTopOf="@+id/btn_unbind"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.46"
app:layout_constraintStart_toEndOf="@+id/btn_msg_bind" />
</android.support.constraint.ConstraintLayout>
接下来看一下service启动的过程:
点击“启动service”按钮:查看logcat:
09-25 14:03:09.307 16466-16466/com.xyd.servicedemo I/BookService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.BookService.onCreate(BookService.kt:18)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = BookService
│ args[1] = onCreate
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.BookService.onStartCommand(BookService.kt:22)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = BookService
│ args[1] = onStartCommand
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
从log可以看到,当使用startService()方式启动service时,service调用了onCreate 和 onStartCommand方法,service就被启动了。startservice的启动过程可以看这篇文章
然后我们再停止该service:
09-25 14:09:14.074 16466-16466/com.xyd.servicedemo I/BookService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.BookService.onDestroy(BookService.kt:28)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = BookService
│ args[1] = onDestroy
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
停止service调用的是:stopService(),当服务停止时,调用了service的onDestroy方法。
通过上边的例子可以看到通过startservice启动的service的生命周期,可以通过相应的方法管理service,并且启动的service不依赖与启动它的Activity,如果当前activity销毁,service也不会被销毁,还是会在后台运行,感兴趣的朋友可以试试。
service创建及使用(绑定状态)
创建同上:具体步骤不写了,直接上代码吧!
service代码:
class MovieService : Service()
private val TAG = "MovieService"
private var movieBinder = MovieService.MovieBinder(this@MovieService)
private var isRun: Boolean = true
var count: Int = 0
var movieName: String = ""
private lateinit var myThread: Thread
override fun onCreate()
super.onCreate()
LogUtils.i(TAG,"onBind")
myThread = object : Thread()
override fun run()
println("running from Thread: $Thread.currentThread()")
while (isRun)
try
Thread.sleep(2000)
catch (e: Exception)
count++
movieName = "复仇者联盟$count"
println(movieName)
myThread.start()
override fun onBind(p0: Intent?): IBinder
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
LogUtils.i(TAG,"onBind")
return movieBinder
class MovieBinder(private val movieService: MovieService) : Binder()
val TAG = "MovieBinder"
fun getMovieService() : MovieService
LogUtils.i(TAG,"getMovieService")
return movieService
override fun unbindService(conn: ServiceConnection?)
super.unbindService(conn)
LogUtils.i(TAG,"unbindService")
override fun onDestroy()
super.onDestroy()
isRun = false
LogUtils.i(TAG,"onDestroy")
activity代码已在上个例子中贴出,请查看。需要注意的是,与startservice方式不同的是,bindservice时需要创建一个ServiceConnection的实例,在bindservice时传递给service,该实例的作用是客户端与服务端通讯的媒介,具体可看一下这篇文章
运行:直接点击“绑定service”按钮,查看log:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.MovieService.onBind(MovieService.kt:45)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = MovieService
│ args[1] = onBind
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-25 14:32:52.109 16821-18011/com.xyd.servicedemo I/System.out: running from Thread: Thread[Thread-4,5,main]
09-25 14:32:52.109 16821-16821/com.xyd.servicedemo I/MainActivity:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.MainActivity.onServiceConnected(MainActivity.kt:52)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = MainActivity
│ args[1] = onServiceConnected
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-25 14:32:52.110 16821-16821/com.xyd.servicedemo I/MovieService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.MovieService$MovieBinder.getMovieService(MovieService.kt:53)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = MovieBinder
│ args[1] = getMovieService
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
通过bindservice后,服务启动,并且在客户端的ServiceConnection中回掉了onServiceConnected()方法,表示客户端已与服务端建立了连接,此时客户端是可以和服务端单向通讯的。如果是绑定状态的service,是依赖于启动它的activity的,当该activity销毁后,绑定的service也会被销毁。
接下来看一下客户端与服务端的通讯:
实例:客户端的代码一贴出,下边看一下服务端的代码
/**
* Created by zejian
* Time 2016/10/3.
* Description:Messenger服务端简单实例,服务端进程
*/
//此变量定义在类外部就可以被全包访问
val SEND_MESSAGE_CODE : Int = 0x0001
//服务端的消息处理
class InComingHandler : Handler()
override fun handleMessage(msg: Message?)
super.handleMessage(msg)
if (msg != null)
when (msg.what)
SEND_MESSAGE_CODE ->
LogUtils.i("接受到客户端消息:" + msg.obj)
//接受完客户端的消息后需要返回给客户端消息
//通过msg.replyTo 方法 获取客户端的messenger
val clientMessenger = msg.replyTo
//获取到messenger之后,在通过客户端的messenger给客户端发送消息
val msg = Message.obtain()
msg.what = RECEIVE_MESSAGE_CODE
msg.obj = "hello client!!!"
Thread.sleep(3000)
clientMessenger.send(msg)
else ->
LogUtils.i("未接受到客户端消息")
private val mMessenger = Messenger(InComingHandler())
class MusicService : Service()
override fun onBind(p0: Intent?): IBinder?
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
return mMessenger.binder
主要的处理逻辑已在代码中标明,请自行查看。
下面解决几个问题:
- 1、Service的start和bind状态有什么区别?
首先第一个问题:
- Service的start和bind状态的区别:首先是启动方式不同,start是直接启动,而bind是依赖于组件启动的,其次是启动的生命周期不同,start启动时执行的是onCreate
、onStartCommand的方法,而bind启动执行的是onBind方法。最后是start方式启动的service可以独立于组件运行,组件销毁之后,service不会停止运行,而bind方式启动的service则是依附于组件,组件销毁后,service会被强制停止运行。
- 2、同一个Service,先startService,然后再bindService,如何把它停止掉?
这个问题可以通过例子来看:新建一个service,并且在清单文件中注册:
class StartAndBindService : Service()
val TAG = "StartAndBindService"
override fun onBind(intent: Intent): IBinder?
LogUtils.i(TAG,"onBind")
return null
override fun onCreate()
super.onCreate()
LogUtils.i(TAG,"onCreate")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
LogUtils.i(TAG,"onStartCommand")
return super.onStartCommand(intent, flags, startId)
override fun onDestroy()
super.onDestroy()
LogUtils.i(TAG,"onDestroy")
然后在activity中新建两个按钮并设置点击事件,一个按钮是start,一个按钮是bind,运行之后,先点击start,然后点击bind,会出现以下结果:
09-26 12:59:55.249 4898-4898/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onCreate(StartAndBindService.kt:19)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onCreate
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-26 12:59:55.255 4898-4898/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onStartCommand(StartAndBindService.kt:23)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onStartCommand
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-26 12:59:57.826 4898-4898/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onBind(StartAndBindService.kt:13)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onBind
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
可以看出先启动,然后在bind,两种启动都会执行,但是如果已这种方式启动之后,调用stopservice,service不会被停止,而调用unbindservice后service才会被停止,由此可见,service由start方式启动,然后在调用bind之后,是先启动,然后在和组件绑定,其实只是一个service,因为onstart方法已被启用,所以看不出来,其实在调用onbind的时候,不会再走onstart方法。
-
3、你有注意到Service的onStartCommand方法的返回值吗?不同返回值有什么区别?
这个问题可以看这篇文章,这个反之没有研究过 -
4、Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?
这个可以在service中打log查看,咱们来看看:
09-26 13:34:43.271 5937-5937/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onCreate(StartAndBindService.kt:25)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onCreate运行在主线程
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-26 13:34:43.273 5937-5937/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onStartCommand(StartAndBindService.kt:41)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onStartCommand运行在主线程
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onStart(StartAndBindService.kt:34)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onStart运行在主线程
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
09-26 13:34:47.690 5937-5937/com.xyd.servicedemo I/StartAndBindService:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.xyd.servicedemo.services.StartAndBindService.onDestroy(StartAndBindService.kt:51)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ args[0] = StartAndBindService
│ args[1] = onDestroy运行在主线程
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
具体使用的判断为:Looper.getMainLooper() == Looper.myLooper()
以上是关于android学习笔记 - service(kotlin实现)的主要内容,如果未能解决你的问题,请参考以下文章