后臺服務(wù)與廣播消息android_第1頁
后臺服務(wù)與廣播消息android_第2頁
后臺服務(wù)與廣播消息android_第3頁
后臺服務(wù)與廣播消息android_第4頁
后臺服務(wù)與廣播消息android_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、蘇州大學計算機科學與技術(shù)學院第第4章章 后臺服務(wù)與廣播消息后臺服務(wù)與廣播消息蘇州大學計算機科學與技術(shù)學院4.1 Service應用4.2 接收廣播消息4.3 相關(guān)閱讀材料:Android開源庫EventBus4.4 本章小結(jié)蘇州大學計算機科學與技術(shù)學院本章導讀Service和BroadcastReceiver均屬Android 系統(tǒng)四大組件。Service只能后臺運行,并且可以和其他組件進行交互。而廣播是一種廣泛運用的在應用程序之間傳輸信息的機制,BroadcastReceiver是對發(fā)送出來的廣播進行過濾接收并響應的一類組件。蘇州大學計算機科學與技術(shù)學院4.1 Service應用4.1.1

2、簡介Service可以在很多場合的應用中使用,比如播放多媒體的時候用戶啟動了其他Activity這個時候程序要在后臺繼續(xù)播放,比如檢測SD卡上文件的變化,再或者在后臺記錄你地理信息位置的改變等等,總之服務(wù)總是藏在后臺的。Service的啟動有兩種方式:context.startService() 和context.bindService()。蘇州大學計算機科學與技術(shù)學院4.1.2 進程內(nèi)服務(wù)1Service啟動流程context.startService() 啟動流程:context.startService()onCreate()onStart()Service runningcontext

3、.stopService()onDestroy()Service stopcontext.bindService()啟動流程:context.bindService()onCreate()onBind()Service running onUnbind()onDestroy()Service stop蘇州大學計算機科學與技術(shù)學院2Service生命周期 Service的生命周期并不像Activity那么復雜,它只繼承了onCreate()、onStart()、onDestroy()三個方法。 當我們第一次啟動Service時,先后調(diào)用了onCreate()、onStart()這兩個方法;當停止

4、Service時,則執(zhí)行onDestroy()方法。 這里需要注意的是,如果Service已經(jīng)啟動了,當我們再次啟動Service時,不會再執(zhí)行onCreate()方法,而是直接執(zhí)行onStart()方法。 它可以通過Service.stopSelf()方法或者Service.stopSelfResult()方法來停止自己,只要調(diào)用一次stopService()方法便可以停止服務(wù),無論調(diào)用了多少次的啟動服務(wù)方法。蘇州大學計算機科學與技術(shù)學院3startService示例4bindService示例詳細內(nèi)容參見教學視頻蘇州大學計算機科學與技術(shù)學院4.1.3 跨進程服務(wù)1AIDL機制由于每個應用程

5、序都運行在自己的進程空間,并且可以從應用程序UI運行另一個服務(wù)進程,而且經(jīng)常會在不同的進程間傳遞對象。在Android平臺,一個進程通常不能訪問另一個進程的內(nèi)存空間,所以要想對話,需要將對象分解成操作系統(tǒng)可以理解的基本單元,并且有序的通過進程邊界。Android提供了AIDL工具來處理這項工作。蘇州大學計算機科學與技術(shù)學院AIDL(Android Interface Definition Language)是一種IDL語言,用于生成可以在Android設(shè)備上兩個進程之間進行進程間通信(interprocess communication,IPC)的代碼。如果在一個進程中(例如Activity)

6、要調(diào)用另一個進程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數(shù)。蘇州大學計算機科學與技術(shù)學院在Android中,每個應用程序都有自己的進程, Java中是不支持跨進程內(nèi)存共享的。因此要傳遞對象,需要把對象解析成操作系統(tǒng)能夠理解的數(shù)據(jù)格式,以達到跨界對象訪問的目的。在Java EE中,采用RMI通過序列化傳遞對象。在Android中,則采用AIDL(Android Interface Definition Language:接口描述語言)方式實現(xiàn)。蘇州大學計算機科學與技術(shù)學院AIDL是一種接口定義語言,用于約束兩個進程間的通訊規(guī)則,供編譯器生成代碼,實現(xiàn)Android設(shè)

7、備上的兩個進程間通信。進程之間的通信信息,首先會被轉(zhuǎn)換成AIDL協(xié)議消息,然后發(fā)送給對方,對方收到AIDL協(xié)議消息后再轉(zhuǎn)換成相應的對象。由于進程之間的通信信息需要雙向轉(zhuǎn)換,所以Android采用代理類在背后實現(xiàn)了信息的雙向轉(zhuǎn)換,代理類由Android編譯器生成,對開發(fā)人員來說是透明的。蘇州大學計算機科學與技術(shù)學院2選擇AIDL的使用場合官方文檔特別提醒我們何時使用AIDL是必要的:只有你允許客戶端從不同的應用程序為了進程間的通信而去訪問你的Service,以及想在你的Service處理多線程。蘇州大學計算機科學與技術(shù)學院4.2 接收廣播消息4.2.1 簡介1廣播發(fā)送者和廣播接收者Android

8、廣播分為兩個方面:廣播發(fā)送者和廣播接收者。通常情況下,BroadcastReceiver指的就是廣播接收者(廣播接收器),用于異步接收廣播Intent。廣播Intent是通過調(diào)用Context.sendBroadcast()發(fā)送、BroadcastReceiver()接收。廣播Intent的發(fā)送是通過調(diào)用Context.sendBroadcast()、Context.sendOrderedBroadcast()、Context.sendStickyBroadcast()來實現(xiàn)的。通常一個廣播Intent可以被訂閱了此Intent的多個廣播接收者所接收。蘇州大學計算機科學與技術(shù)學院Broadca

9、stReceiver 接收廣播方式一般有兩種:(1)Normal Broadcasts(正常廣播),用 Context.sendBroadcast()發(fā)送是完全異步的,它們都運行在一個未定義的順序,通常是在同一時間。(2)Ordered Broadcasts(有序廣播),用 Context.sendOrderedBroadcast()發(fā)送每次被發(fā)送到一個receiver。蘇州大學計算機科學與技術(shù)學院2使用場景(1)同一App內(nèi)部的同一組件內(nèi)的消息通信(單個或多個線程之間);(2)同一App內(nèi)部的不同組件之間的消息通信(單個進程);(3)同一App具有多個進程的不同組件之間的消息通信;(4)不同

10、App之間的組件之間消息通信;(5)Android系統(tǒng)在特定情況下與App之間的消息通信。蘇州大學計算機科學與技術(shù)學院3實現(xiàn)原理(1)廣播接收者BroadcastReceiver通過Binder機制向AMS(Activity Manager Service)進行注冊;(2)廣播發(fā)送者通過Binder機制向AMS發(fā)送廣播;(3)AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發(fā)送到BroadcastReceiver(一般情況下是Activity)相應的消息循環(huán)隊列中;(4)消息循環(huán)執(zhí)行拿到此廣播,回調(diào)BroadcastRece

11、iver中的onReceive()方法。蘇州大學計算機科學與技術(shù)學院4實際應用中的適用性(1):同一App內(nèi)部的同一組件內(nèi)的消息通信(單個或多個線程之間),實際應用中肯定是不會用到廣播機制的(雖然可以用),無論是使用擴展變量作用域、基于接口的回調(diào)還是Handler-post/Handler-Message等方式,都可以直接處理此類問題。(2):同一App內(nèi)部的不同組件之間的消息通信(單個進程),對于此類需求,在有些較復雜的情況下單純的依靠基于接口的回調(diào)等方式不好處理,此時可以直接使用EventBus等。(3)(4)(5):由于涉及不同進程間的消息通信,此時根據(jù)實際業(yè)務(wù)使用廣播機制會顯得非常適宜

12、。蘇州大學計算機科學與技術(shù)學院4.2.2 發(fā)送廣播1自定義BroadcastReceiver自定義廣播接收器需要繼承基類BroadcastReceivre,并實現(xiàn)抽象方法onReceive(context, intent)方法。廣播接收器接收到相應廣播后,會自動回到onReceive()方法。默認情況下,廣播接收器也是運行在UI線程,因此,onReceive方法中不能執(zhí)行太耗時的操作,否則將因此ANR(Application Not Responding,應用沒有響應)。一般情況下,根據(jù)實際業(yè)務(wù)需求,onReceive方法中都會涉及到與其他組件之間的交互,如發(fā)送Notification、啟動s

13、ervice等。蘇州大學計算機科學與技術(shù)學院下面代碼片段是一個簡單的廣播接收器的自定義:public class MyBroadcastReceiver extends BroadcastReceiver public static final String TAG = MyBroadcastReceiver; Override public void onReceive(Context context, Intent intent) Log.d(TAG, intent: + intent); String name = intent.getStringExtra(name); 蘇州大學計算機

14、科學與技術(shù)學院一個BroadcastReceiver對象只有在被調(diào)用onReceive(Context, Intent)才有效,當從該函數(shù)返回后,該對象就無效了,而結(jié)束生命周期。因此從這個特征可以看出,在所調(diào)用的onReceive(Context,Intent)函數(shù)里,不能有過于耗時的操作,不能使用線程來執(zhí)行。對于耗時的操作,應該在startService中來完成。因為當?shù)玫狡渌惒讲僮魉祷氐慕Y(jié)果時,BroadcastReceiver可能已經(jīng)無效了。蘇州大學計算機科學與技術(shù)學院2BroadcastReceiver注冊類型1)靜態(tài)注冊直接在AndroidManifest.xml文件中進行注冊:

15、. . .蘇州大學計算機科學與技術(shù)學院其中,需要注意的屬性有以下:(1)android:exported此broadcastReceiver能否接收其他App的發(fā)出的廣播,其默認值是由receiver中有無intent-filter決定的,如果有intent-filter,默認值為true,否則為false。(2)android:name此BroadcastReceiver類名。(3)android:permission如果設(shè)置,具有相應權(quán)限的廣播發(fā)送方發(fā)送的廣播才能被此BroadcastReceiver所接收。(4)android:processBroadcastReceiver運行所處的進

16、程。默認為App的進程??梢灾付í毩⒌倪M程。(Android四大基本組件都可以通過此屬性指定自己的獨立進程)。蘇州大學計算機科學與技術(shù)學院常見的注冊形式有: 蘇州大學計算機科學與技術(shù)學院2)動態(tài)注冊動態(tài)注冊時,無須在AndroidManifest中注冊組件。直接在代碼中通過調(diào)用Context的registerReceiver函數(shù),可以在程序中動態(tài)注冊BroadcastReceiver。registerReceiver的定義形式如下:registerReceiver(BroadcastReceiver receiver, IntentFilter filter)registerReceiver(

17、BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)蘇州大學計算機科學與技術(shù)學院3BroadcastReceiver示例詳細內(nèi)容參見教學視頻蘇州大學計算機科學與技術(shù)學院4.2.3 有序廣播有序廣播的有序廣播中的“有序”是針對廣播接收者而言的,指的是發(fā)送出去的廣播被BroadcastReceiver按照先后循序接收。有序廣播的定義過程與普通廣播無異,只是其主要發(fā)送方式變?yōu)椋簊endOrderedBroadcast(intent, receiverPermiss

18、ion, .)。蘇州大學計算機科學與技術(shù)學院對于有序廣播,其主要特點是:(1)多個具當前已經(jīng)注冊且有效的BroadcastReceiver接收有序廣播時,是按照先后順序接收的,先后順序判定標準為:將當前系統(tǒng)中所有有效的動態(tài)注冊和靜態(tài)注冊的BroadcastReceiver按照priority屬性值從大到小排序,對于具有相同的priority的動態(tài)廣播和靜態(tài)廣播,動態(tài)廣播會排在前面。(2)先接收的BroadcastReceiver可以對此有序廣播進行截斷,使后面的BroadcastReceiver不再接收到此廣播,也可以對廣播進行修改,使后面的BroadcastReceiver接收到廣播后解析得

19、到錯誤的參數(shù)值。蘇州大學計算機科學與技術(shù)學院4.2.4 接收系統(tǒng)廣播消息Android系統(tǒng)中內(nèi)置了多個系統(tǒng)廣播,只要涉及到手機的基本操作,基本上都會發(fā)出相 應的系統(tǒng)廣播。如:開啟啟動,網(wǎng)絡(luò)狀態(tài)改變,拍照,屏幕關(guān)閉與開啟,點亮不足等等。每個系統(tǒng)廣播都具有特定的intent-filter,其中主要包括具體的action,系統(tǒng)廣播發(fā)出后,將被相應的BroadcastReceiver接收。系統(tǒng)廣播在系統(tǒng)內(nèi)部當特定事件發(fā)生時,有系統(tǒng)自動發(fā)出。蘇州大學計算機科學與技術(shù)學院4.3 相關(guān)閱讀材料:Android開源庫EventBus1使用背景在編程過程中,當我們想通知其他組件某些事情發(fā)生時,我們通常使用觀察者

20、模式,在jdk1.5中已經(jīng)幫助我們實現(xiàn)了觀察者模式,我們只需要簡單地繼承一些類就可以快速使用觀察者模式。當此類需求相對簡單時,通過接口以實現(xiàn)回調(diào)等方式可以完成,但是當不同組件/控件之間的非常關(guān)系紛繁復雜時,基于接口的方案不僅使得代碼非常繁瑣,同時使得程序邏輯混亂。基于此,Android開源庫EventBus,為此類需求的實現(xiàn)提供了非常方便的方案,可以很方便的幫助我們實現(xiàn)觀察者模式。蘇州大學計算機科學與技術(shù)學院2什么是EventBusEventBus,也即事件總線。EventBus是一款針對Android優(yōu)化的發(fā)布/訂閱事件總線。主要功能是替代Intent,Handler,BroadCast在F

21、ragment,Activity,Service,線程之間傳遞消息,優(yōu)點是開銷小,代碼更優(yōu)雅,以及將發(fā)送者和接收者解耦。蘇州大學計算機科學與技術(shù)學院3實現(xiàn)步驟(1)下載EventBus庫;(EvnetBus的下載地址:https:/ void onUpdate();在EventBus中的觀察者通常有四種訂閱函數(shù)(就是某件事情發(fā)生被調(diào)用的方法):onEvent,onEventMainThread,onEventBackground,onEventAsync。蘇州大學計算機科學與技術(shù)學院5MyEventBusDemo示例詳細內(nèi)容參見教學視頻蘇州大學計算機科學與技術(shù)學院4.4本章小結(jié)(1)Servi

22、ce用來在后臺處理一些比較復雜的操作,最典型的例子就是音樂播放器的后臺播放。雖然Activity中也能完成這樣的功能,不過當系統(tǒng)內(nèi)存緊張時會先把Activity“殺掉”,而很少有Service會“死掉”。另外,一般Activity會在onDestroy時release一些內(nèi)容,所以,當界面被覆蓋時,Activity就不安全了。(2)Service不是一個單獨的進程,除非單獨聲明,否則它不會運行在單獨的進程中,而是和啟動它的程序運行在同一個進程中。Service也不是線程,這意味著它將在主線程里運行。蘇州大學計算機科學與技術(shù)學院(3)Service與Thread的區(qū)別在于:Thread是程序執(zhí)行

23、的最小單元,可以用Thread來執(zhí)行一些異步的操作。而Service是Android的一種機制,當它運行的時候如果是Local Service,那么對應的Service是運行在主進程的main線程上的。如果是Remote Service,那么對應的Service則是運行在獨立進程的main線程上。(4)Thread 的運行是獨立的,也就是說當一個Activity被finish之后,如果沒有主動停止Thread或者Thread里的run方法沒有執(zhí)行完畢的話,Thread 也會一直執(zhí)行。因此這里會出現(xiàn)一個問題:當Activity被finish之后,不再持有該Thread的引用,也就是不能再控制該T

24、hread。另一方面,沒有辦法在不同的Activity中對同一Thread 進行控制。蘇州大學計算機科學與技術(shù)學院(5)因此可以把Service想象成一種消息服務(wù),可以在任何有Context的地方調(diào)用 Context.startService、Context.stopService、Context.bindService、Context.unbindService來控制它,也可以在Service 里注冊BroadcastReceiver,通過發(fā)送Broadcast來達到控制的目的,這些都是Thread做不到的。 (6)啟動Service有兩種方法:Context.startService()和

25、Context.bindService()。對于Context.startService(),調(diào)用者(Client)與服務(wù)端之間沒有關(guān)聯(lián),即使調(diào)用者退出,服務(wù)仍可運行。對于Context.bindService(),調(diào)用者與服務(wù)端綁定在一起,可以多個調(diào)用者綁定一個服務(wù)端,當所有的調(diào)用者退出,服務(wù)端也就終止。蘇州大學計算機科學與技術(shù)學院(7)如果有耗時操作在Service里,就必須開啟一個單獨的線程來處理。(8)IntentService是繼承自Service的。IntentService相對于Service來說,其優(yōu)點在于,使用隊列的方式將請求的Intent加入隊列,然后開啟一個worker

26、thread(線程)來處理隊列中的Intent;對于異步的startService請求,IntentService會處理完成一個之后再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程序的主線程,這里就給我們提供了一個思路,如果有耗時的操作與其在Service里面開啟新線程還不如使用IntentService來處理耗時操作。 蘇州大學計算機科學與技術(shù)學院(9)廣播接收者(BroadcastReceiver)用于接收廣播Intent,廣播Intent的發(fā)送是通過調(diào)用Context.sendBroadcast()、Context.sendOrderedBroad

27、cast()來實現(xiàn)的。通常一個廣播Intent可以被訂閱了此Intent的多個廣播接收者所接收。(10)BroadcastReceiver自身并不實現(xiàn)圖形用戶界面,但是當它收到某個通知后, BroadcastReceiver可以啟動Activity作為響應,或者通過NotificationMananger提醒用戶,或者啟動Service等等。(11)在Android里面有各種各樣的廣播,比如電池的使用狀態(tài),電話的接收和短信的接收都會產(chǎn)生一個廣播,應用程序開發(fā)者也可以監(jiān)聽這些廣播并做出程序邏輯的處理。蘇州大學計算機科學與技術(shù)學院(12)BroadcastReceiver生命周期只有十秒左右,如果在onReceive()內(nèi)做超過十秒內(nèi)的事情,就會報錯。每次廣播到來時,會重新創(chuàng)建BroadcastReceiver對象,并且調(diào)用 onRecei

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論