這個真拖延太久了傻寂,必須把這個筆記完成。儿普,崎逃,看了一下2016年的草稿掷倔,從Android 6.0 這都要10.0了眉孩。
一、Service釋義、作用浪汪、分類巴柿。
Service是Android應(yīng)用程序中的一個組件,與用戶不進(jìn)行交互死遭,可以長期的執(zhí)行在后臺广恢。
分類:
Android O 之前,創(chuàng)建前臺服務(wù)的方式通常是先創(chuàng)建一個后臺服務(wù)呀潭,然后將該服務(wù)推到前臺钉迷。Android O及Android P,系統(tǒng)不允許后臺應(yīng)用創(chuàng)建后臺服務(wù)钠署,Android O 引入了一種全新的方法糠聪,即ContextCompat.startForegroundService() ,以在前臺啟動新服務(wù)谐鼎。Service分為如下三類
1.foreground service
fg Service執(zhí)行一些對于用戶來說是可感知的操作舰蟆,如audio應(yīng)用使用fg service來播放歌曲。
2.background service
bg service執(zhí)行的操作對用戶而言是不可感知的狸棍。
3.bound service
bound service主要是提供c/s接口身害,允許組件與service進(jìn)行通信,或者是跨進(jìn)程的通信草戈。
這是由于啟動方式的不同導(dǎo)致了三種service,
startService -> background service.
startForegroundService -> foreground service
bindService -> bound service
二塌鸯、使用
2.1聲明
Service是Android中的四大組件,使用它一定要在AndroidManifest.xml中聲明猾瘸,在AndroidManifest.xml中聲明是為了讓PackageManagerService能解析出該Service, 并建立對應(yīng)的數(shù)據(jù)結(jié)構(gòu)
<service android:name=".myservice"
android:enabled="true"
android:exported="true"
android:icon="@drawable/background_blue"
android:label="string"
android:process="string"
android:permission="string">
</service>
說明:
name:服務(wù)的路徑
enabled:表示系統(tǒng)是否能夠?qū)嵗摻M件
exported:表示該服務(wù)是否能夠被其他應(yīng)用程序組件所調(diào)用或者交互
android:process 是否需要在單獨的進(jìn)程中運行,當(dāng)設(shè)置為android:process=”:remote”時界赔,代表Service在單獨的進(jìn)程中運行。注意“:”很重要牵触,它的意思是指要在當(dāng)前進(jìn)程名稱前面附加上當(dāng)前的包名淮悼,所以“remote”和”:remote”不是同一個意思,前者的進(jìn)程名稱為:remote揽思,而后者的進(jìn)程名稱為:App-packageName:remote袜腥。
android:isolatedProcess 設(shè)置 true 意味著,服務(wù)會在一個特殊的進(jìn)程下運行钉汗,這個進(jìn)程與系統(tǒng)其他進(jìn)程分開且沒有自己的權(quán)限羹令。與其通信的唯一途徑是通過服務(wù)的API(bind and start)。
2.2啟動
1.startService()
startService()開啟服務(wù)時服務(wù)執(zhí)行的生命周期方法是
onCreate()----onStartCommand()-----onStop()----onDestory()
其中onCreate()會在服務(wù)第一次創(chuàng)建的時候調(diào)用损痰,當(dāng)多次調(diào)用startService方法的時候福侈,onCreate只會執(zhí)行一次,而onStartCommand會執(zhí)行多次卢未,onDestroy方法會在服務(wù)銷毀的時候進(jìn)行調(diào)用
服務(wù)的銷毀 該方式下啟動的服務(wù)可以調(diào)用stopService(Intent intent)或者stopSelf()來進(jìn)行服務(wù)的銷毀肪凛。
2.bindService
bindService綁定服務(wù)時服務(wù)執(zhí)行的生命周期方法是
onCreate()----onBind()-----onUnbind()----onStop()----onDestory()
onCreate堰汉,onBind 會在bindService第一次調(diào)用的時候去執(zhí)行,如果多次調(diào)用bindService伟墙,onCreate和onBind也就執(zhí)行一次翘鸭,onUnbind和onDestroy會在解綁服務(wù)的時候進(jìn)行調(diào)用。
服務(wù)的解綁 該方式下綁定的服務(wù)需要調(diào)用unbindService(ServiceConnection mConnection)方法來進(jìn)行服務(wù)的解綁操作戳葵。
綁定服務(wù)的最大作用就是用來實現(xiàn)對Service執(zhí)行的任務(wù)進(jìn)行進(jìn)度監(jiān)控就乓。
三、筆記
3.1
服務(wù)類似于其他應(yīng)用程序的對象拱烁,運行在主線程中生蚁。這就意味著你如果在服務(wù)中進(jìn)行耗時的操作,你需要開啟一個子線程去處理這個操作戏自,不然在服務(wù)中超過20秒未響應(yīng)會發(fā)生ANR導(dǎo)致程序崩潰守伸。IntentService的出現(xiàn)就是為了解決在服務(wù)中操作耗時任務(wù)的。
3.2
在Android中綁定式服務(wù)bindService會隨著Activity的結(jié)束而結(jié)束浦妄,但是啟動式服務(wù)startService不受Activity的影響尼摹。
3.3service與線程的區(qū)別
Thread 是程序執(zhí)行的最小單元,它是分配CPU的基本單位剂娄,android系統(tǒng)中UI線程也是線程的一種蠢涝,當(dāng)然Thread還可以用于執(zhí)行一些耗時異步的操作。
Service是Android的一種機制阅懦,服務(wù)是運行在主線程上的和二,它是由系統(tǒng)進(jìn)程托管。它與其他組件之間的通信類似于client和server耳胎,是一種輕量級的IPC通信惯吕,這種通信的載體是binder,它是在linux層交換信息的一種IPC怕午,而所謂的Service后臺任務(wù)只不過是指沒有UI的組件罷了废登。
二者沒有任何關(guān)系
3.3 顯/隱式 啟動
//顯示啟動
Intent intent = new Intent(this,ForegroundService.class);
startService(intent);
隱式啟動:
但是Android 5.0一出來后,其中有個特性就是Service Intent must be explitict郁惜,也就是說從Lollipop開始堡距,service服務(wù)必須采用顯示方式啟動。 需要設(shè)置一個Action兆蕉,我們可以把Action的名字設(shè)置成Service的全路徑名字羽戒,在這種情況下android:exported默認(rèn)為true。
3.4兼容處理
Android 8.0 還對特定函數(shù)做出了以下變更:
- 如果針對 Android 8.0 的應(yīng)用嘗試在不允許其創(chuàng)建后臺服務(wù)的情況下使用 startService() 函數(shù)虎韵,則該函數(shù)將引發(fā)一個 IllegalStateException易稠。
- 新的 Context.startForegroundService() 函數(shù)將啟動一個前臺服務(wù)。現(xiàn)在包蓝,即使應(yīng)用在后臺運行驶社,系統(tǒng)也允許其調(diào)用 Context.startForegroundService()呆奕。不過,應(yīng)用必須在創(chuàng)建服務(wù)后的五秒內(nèi)調(diào)用該服務(wù)的 startForeground() 函數(shù)衬吆。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
startForegroundService中主要是通知創(chuàng)建service 并發(fā)送一個延遲5s的msg,5s后就會拋出異常绳泉。
在service創(chuàng)建之后會調(diào)用onCreate中手動添加的startForeground逊抡,它的作用是添加notification避免 “null notification”(startForeground方法參數(shù)會傳入一個notification);同時移除了startForegroundService中發(fā)出的超時msg 避免了Context.startForegroundService() did not then call Service.startForeground()異常零酪。