Activity 中能夠有兩種方式啓動 Service,不一樣方式啓動時 Service 的生命週期也不同,如今在 Activity 中定義四個 Button,分別是 startService
、stopService
、bindService
、unbindService
,Service 中各生命週期中分別打印 Log 日誌,經過日誌查看生命週期執行狀況:java
// MainActivity.kt class MainActivity : AppCompatActivity(){ var mService: MyService? = null var isBind = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val intent = Intent(this, MyService::class.java) val conn = object : ServiceConnection { override fun onServiceDisconnected(name: ComponentName?) { Log.e("abc", "-- Activity 中 onServiceDisconnected --") } override fun onServiceConnected(name: ComponentName?, service: IBinder?) { mService = (service as MyService.MyBinder).getService() Log.e("abc", "-- Activity 中 onServiceConnected --") } } startService.setOnClickListener { startService(intent) } stopService.setOnClickListener { stopService(intent) } bindService.setOnClickListener { isBind = bindService(intent, conn, Context.BIND_AUTO_CREATE) } unBindService.setOnClickListener { if (isBind) { isBind = false unbindService(conn) } } } }
// MyService.kt class MyService: Service() { override fun onBind(intent: Intent?): IBinder? { Log.e("abc", "-- onBind --") return MyBinder() } override fun onCreate() { super.onCreate() Log.e("abc", "-- onCreate --") } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.e("abc", "-- onStartCommand --") return super.onStartCommand(intent, flags, startId) } override fun onDestroy() { super.onDestroy() Log.e("abc", "-- onDestroy --") } override fun onUnbind(intent: Intent?): Boolean { Log.e("abc", "-- onUnbind --") return super.onUnbind(intent) } inner class MyBinder : Binder() { fun getService(): MyService { return this@MyService } } }
其實之前 Service 還有個生命週期叫onStart()
,後來被棄用了,它的功能由onStartCommand()
代替。
在 MainActivity 中能夠這樣啓動和中止 Service:git
// 啓動 val intent = Intent(this, MyService::class.java) startService(intent) // 中止 stopService(intent) // Log -- onCreate -- -- onStartCommand -- -- onDestroy --
bindService 方式稍微複雜些:github
// 綁定 val conn = object : ServiceConnection { override fun onServiceDisconnected(name: ComponentName?) {} override fun onServiceConnected(name: ComponentName?, service: IBinder?) { } } bindService(intent, conn, Context.BIND_AUTO_CREATE) // 中止 unbindService(conn) // Log -- onCreate -- -- onBind -- -- onUnbind -- -- onDestroy --
綁定時會執行 onBind
生命週期,解綁時先調用 onUnbind
再調用onDestroy
。框架
若是先用 startService 方式啓動了 Service,再用 bindService 綁定一次(二者順序也能夠顛倒),那麼此時單純的 stopService 或者 unbindService 是沒法終止 Service 的,須要兩者聯合使用才行。具體細化:ide
// Log -- onCreate -- -- onStartCommand -- -- onBind -- // stopService 無反應 // unbindService: -- onUnbind -- -- onDestroy --
調用 stopService 沒有反應,調用 unbindService 時方可銷燬 Service。
-- onCreate -- -- onStartCommand -- -- onBind -- // unbindService -- onUnbind -- // stopService -- onDestroy --
調用 unbindService 只能解綁(onUnbind)不能銷燬,調用 stopService 時才能夠銷燬 Service
onStartCommand
方法會執行屢次;但屢次使用 bindService 時,onBind
只執行一次。其實從前面的代碼中也能夠看出,在 MainActivity 中,能夠獲取到 Service 的引用(具體來講是onServiceConnected
中),Service 調用 Activity 中的方法主要講講。this
回看 Service 的onBind
生命週期能夠發現,該方法返回的是一個 IBinder 類型,咱們在具體實現是返回的是它子類的子類(IBinder 的 子類是 Binder,Binder 的子類是 MyBinder),這是一種多態(不懂多態的本身查一下蛤,這篇文章不是介紹多態的,展開說太長了):日誌
// MyBinder 是 Service 我本身定義的裏面的內部類 inner class MyBinder : Binder() { fun getService(): MyService { return this@MyService } } // Binder 源碼 public class Binder implements IBinder { ...代碼省略 } // onBind 生命週期 override fun onBind(intent: Intent?): IBinder? { return MyBinder() } // bindService 方式打開 Service 時用到的 conn val conn = object : ServiceConnection { override fun onServiceDisconnected(name: ComponentName?) { } override fun onServiceConnected(name: ComponentName?, service: IBinder?) { mService = (service as MyService.MyBinder).getService() } }
如今,能夠用 mService 對象調用 Service 中的任何方法,好比 printTxtcode
fun printTxt(txt : String) { Log.e("abc", "-- this is txt -- $txt") }
其實我以爲還能夠直接 new 一個 MyService 對象 mService2,而後
myService2.printTxt("裝逼")
,好像也沒啥區別。
Service 沒有 Activity 的引用,因此能夠經過接口回調或者廣播的方式向 Activity 傳遞數據。對象
定義接口:接口
interface CallBack { fun call(index: Int) }
Service 中初始化:
private var callBack:CallBack ?= null fun setListener(callBack: CallBack){ this.callBack = callBack }
Activity 實現 CallBack(或者用 匿名內部類):
class MainActivity : AppCompatActivity(), CallBack { override fun call(index: Int) { Log.e("abc", "This is index value : $index") } } mService.setListener(this@MainActivity) // 或者 mService!!.setListener(object :CallBack{ override fun call(index: Int) { Log.e("abc", "This is index value : $index") } })
Service 中有了 callBack 對象,就能夠主動向 Activity 傳輸數據了。
用 Android 自帶的 BroadcastReceiver 或者 EventBus 這種第三方框架區別不大,先在 Activity 中註冊接受者,而後在 Service 中發射廣播數據,不具體舉例了。須要說明的是,若是是一個 Service 向多個 Activity 傳遞數據,廣播比回調要好一些。