![Service與多線程_v1_5[1][1].26.ppt_第1頁(yè)](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a1.gif)
![Service與多線程_v1_5[1][1].26.ppt_第2頁(yè)](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a2.gif)
![Service與多線程_v1_5[1][1].26.ppt_第3頁(yè)](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a3.gif)
![Service與多線程_v1_5[1][1].26.ppt_第4頁(yè)](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a4.gif)
![Service與多線程_v1_5[1][1].26.ppt_第5頁(yè)](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Android Service與多線程,1.Service,簡(jiǎn)介,Android提供Service類用于創(chuàng)建隱形的,不需要用戶接口的程序。Service其實(shí)就是沒(méi)有專屬界面的Activity。 通過(guò)Service可以使程序在退出之后仍然能夠?qū)κ录蛴脩舨僮髯龀龇磻?yīng),或者在后臺(tái)繼續(xù)運(yùn)行某些程序功能。例如在退出播放器界面之后,繼續(xù)在后臺(tái)播放音樂(lè),還有瀏覽器在后臺(tái)下載網(wǎng)絡(luò)數(shù)據(jù)。 Android賦予Services比處于不活動(dòng)(inactivity)的Activities更高的優(yōu)先級(jí),所以它們的進(jìn)程不會(huì)輕易被系統(tǒng)殺掉。 在某些極端的情況下(例如為前臺(tái)Activity提供資源),Service可能會(huì)被殺
2、掉,但是只要有足夠的資源,系統(tǒng)會(huì)自動(dòng)重啟Service。,簡(jiǎn)介,在某些需要確保用戶體驗(yàn)的情況下,(例如播放音樂(lè))Service也可以被提高到與前臺(tái)進(jìn)程相同的優(yōu)先級(jí)。 Service是由其他Service,Activity或者Broadcast Receiver開(kāi)始,停止和控制。,簡(jiǎn)介,Service的生命周期狀態(tài)比Activity少一些,只有Create,Bind,Start,Unbind,Destroy,這也是與Activity的不同之處。 通過(guò)startService啟動(dòng)的Service的生命周期狀態(tài)。 通過(guò)bindService啟動(dòng)的Service的生命周期(稍后介紹),onCreate
3、,onDestroy,onUnbind,onBind,onCreate,onDestroy,onStart,開(kāi)始和停止Service,開(kāi)啟Service 在Activity中可以通過(guò)startService(Intent)開(kāi)啟一個(gè)Service。與Activity跳轉(zhuǎn)類似。 Intent intent = new Intent(this,MyService.class); startService(intent); 其中MyService類是開(kāi)發(fā)者自定義的繼承Service的子類。 關(guān)閉Service 在Activity中通過(guò)stopService(Intent)關(guān)閉Service; Inte
4、nt intent = new Intent(this,MyService.class); stopService(intent); 或者在Service中通過(guò)stopSelf()關(guān)閉自身。,如何實(shí)現(xiàn)一個(gè)Service,建立Android工程 Activity:ServiceApplication.java 程序入口,例程將在在這個(gè)Activity中啟動(dòng)Service。 Service:MyService.java 自定義Service。,如何實(shí)現(xiàn)一個(gè)Service,MyService.java public class MyService extends Service Override p
5、ublic IBinder onBind(Intent intent) / 必須實(shí)現(xiàn)的接口 return null; Override public int onStartCommand(Intent intent, int flags, int startId) return Service.START_STICKY; Override public boolean onUnbind(Intent intent) return super.onUnbind(intent); Override public void onDestroy() super.onDestroy(); ,如何實(shí)現(xiàn)一個(gè)
6、Service,ServiceApplication.java public class ServiceApplication extends Activity Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = new Intent(this,MyService.class); startService(intent); ,如何實(shí)現(xiàn)一個(gè)Service,在Android
7、Manifest.xml中注冊(cè)這個(gè)Service ,如何實(shí)現(xiàn)一個(gè)Service,在很多情況下,你可能需要重寫(xiě)onCreate和onStartCommand方法 onStartCommand方法在使用startService方法啟動(dòng)Service的時(shí)候被調(diào)用,在Service的生命周期內(nèi)會(huì)多次被調(diào)用。 onStartCommand方法代替了Android 2.0之前一直使用的onStart方法。通過(guò)onStartCommand方法,我們可以明確告訴操作系統(tǒng),在用戶調(diào)用stopService或者stopSelf方法顯式停止之前被操作系統(tǒng)殺死的Service重啟的時(shí)候要執(zhí)行的操作。,如何實(shí)現(xiàn)一個(gè)Se
8、rvice,Override public int onStartCommand(Intent intent, int flags, int startId) return Service.START_STICKY; 通過(guò)onStartCommand返回的Service常量,我們可以明確指定系統(tǒng)在重啟由于資源搶占被殺死的Service時(shí)執(zhí)行的行為。 Service.START_STICKY 重寫(xiě)onStartCommand和返回Service.START_STICKY實(shí)現(xiàn)與Android 2.0之前onStart相同的效果。 Service. START_REDELIVER_INTENT Se
9、rvice.START_NOT_STICKY (詳見(jiàn)SDK),如何實(shí)現(xiàn)一個(gè)Service,本地進(jìn)程(Local process) AndroidManifest.xml中,節(jié)點(diǎn)下的android:process屬性是可選項(xiàng)。這個(gè)選項(xiàng)告訴系統(tǒng)運(yùn)行Service的進(jìn)程的名稱。一般情況下,節(jié)點(diǎn)下的任何程序組件都是運(yùn)行在創(chuàng)建程序的缺省進(jìn)程中。但是通過(guò)重寫(xiě)這個(gè)屬性,我們可以重新定義運(yùn)行Service的進(jìn)程。 遠(yuǎn)程進(jìn)程(Remote process) 如果屬性是以”:”開(kāi)頭的字符串(例如”:remote”),那么程序?qū)?chuàng)建新的進(jìn)程運(yùn)行Service。 如果屬性是其他名稱,那么程序?qū)⒃谠撁Q的全局進(jìn)程下運(yùn)行
10、Service。,如何實(shí)現(xiàn)一個(gè)Service,如果Service運(yùn)行于本地進(jìn)程中,那么在Service中進(jìn)行大規(guī)模計(jì)算、文件讀寫(xiě)、互聯(lián)網(wǎng)連接時(shí)也會(huì)阻塞UI線程,影響用戶體驗(yàn)。 通常的做法是在onStartCommand中創(chuàng)建子線程,在子線程中進(jìn)行耗時(shí)的操作,操作結(jié)束時(shí)停止Service?;蛘咄ㄟ^(guò)遠(yuǎn)程進(jìn)程運(yùn)行Service。,綁定Activity和Service,由于Service沒(méi)有界面,所以用戶控制Service需要通過(guò)另外一個(gè)Activity來(lái)接收用戶輸入。 然后,通過(guò)綁定Activity與Service,可以實(shí)現(xiàn)Activity與Service之間的交互。例如在Activity中控制音樂(lè)
11、播放Service對(duì)音樂(lè)進(jìn)行開(kāi)始/停止,快進(jìn)/快退等操作。 如果Service運(yùn)行在本地進(jìn)程,即與Activity屬于同一進(jìn)程,則只要在Activity中獲得指向Service的引用,就可以像調(diào)用成員對(duì)象的方法一樣去調(diào)用Service的方法。,綁定Activity和Service,如果Service運(yùn)行在遠(yuǎn)程進(jìn)程中,則Activity與Service的交互屬于進(jìn)程間通訊。跟其他操作系統(tǒng)一樣,Android操作系統(tǒng)也對(duì)進(jìn)程空間進(jìn)行保護(hù),一個(gè)進(jìn)程不能直接訪問(wèn)另一個(gè)進(jìn)程的內(nèi)存空間。 所以進(jìn)程間數(shù)據(jù)交互需要利用Android操作系統(tǒng)提供的進(jìn)程間通訊(IPC)機(jī)制來(lái)實(shí)現(xiàn)。,IPC機(jī)制IBinder,IB
12、inder是遠(yuǎn)程對(duì)象的基本接口,是為高效率進(jìn)程中、進(jìn)程間通訊設(shè)計(jì)的輕量級(jí)遠(yuǎn)程過(guò)程調(diào)用機(jī)制的核心。這個(gè)接口描述了與遠(yuǎn)程對(duì)象交互的抽象協(xié)議。通常我們使用的時(shí)候并不是直接實(shí)現(xiàn)這個(gè)接口,而是繼承自Binder父類。,綁定Activity和Service,Activity和Service交互示意圖,Activity,Binder,Service,IBinder,綁定Activity和Service,MyService.java public class MyService extends Service private IBinder mBinder = new MyBinder(); Override
13、 public IBinder onBind(Intent intent) / 必須實(shí)現(xiàn)的接口 return mBinder; public class MyBinder extends Binder Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException return super.onTransact(code, data, reply, flags); ,綁定Activity和Service,ServiceApplication.
14、java public class ServiceApplication extends Activity private IBinder mBinder; private ServiceConnection mConnection; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); mConncetion = new ServiceConnection() Override public void
15、 onServiceConnected(ComponentName name, IBinder service) mBinder = service; Override public void onServiceDisconnected(ComponentName name) mConnection = null; ; Intent intent = new Intent(this,MyService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); ,綁定Activity和Service,onService
16、Connection的輸入?yún)?shù)IBinder就是Service中onBind返回的Binder對(duì)象。通過(guò)IBinder對(duì)象就可以實(shí)現(xiàn)Activity和Service進(jìn)程間通訊。 通過(guò)配對(duì)的IBinder的transact()方法和Binder的onTransact()方法,可以實(shí)現(xiàn)從IBinder接口發(fā)送消息,在Binder對(duì)象中接收消息,處理消息,再返回的過(guò)程。,綁定Activity和Service,要注意,transact()和onTransact()是一個(gè)同步調(diào)用過(guò)程,意味著線程A調(diào)用transact()后,在線程B完成onTransact()整個(gè)處理過(guò)程之前,線程A都是阻塞著。所以,如
17、果在onTransact()中需要進(jìn)行大規(guī)模計(jì)算時(shí),通常需要在線程A中開(kāi)啟新線程調(diào)用transact()。,綁定Activity和Service,onTransact(int code, Parcel data, Parcel reply,int flags) transact(int code, Parcel data, Parcel reply,int flags) 通過(guò)onTransact和transact交互的數(shù)據(jù)都被封裝在Parcel中 由于IBinder只提供了一個(gè)消息傳遞接口,只能通過(guò)int類型的輸入?yún)?shù)code對(duì)消息進(jìn)行識(shí)別和判斷,AIDL簡(jiǎn)介,AIDL(Android Int
18、erface Description Language)彌補(bǔ)了IBinder接口單一的缺點(diǎn)。 AIDL接口描述文件,語(yǔ)法與普通的Java接口一樣,只是文件擴(kuò)展名為.aidl。 ADT會(huì)根據(jù)這個(gè)描述文件自動(dòng)生成一個(gè)底層基于IBinder機(jī)制,表層提供描述文件所定義方法的接口類。,AIDL簡(jiǎn)介,Aidl文件示例,例子中我們自定義了set、get兩個(gè)方法 ITest.aidl interface IAidlTest /可以看到,aidl文件語(yǔ)法與普通接口一致 void set(int i); int get(); ,AIDL簡(jiǎn)介,ADT會(huì)根據(jù)這個(gè).aidl文件,自動(dòng)生成一個(gè).java接口文件,其中代
19、碼結(jié)構(gòu)如下: public interface IAidlTest extends android.os.IInterface /部分省略 public static abstract class Stub extends android.os.Binder implements com.book.ServiceApplication.IAidlTest /部分省略 private static class Proxy implements com.book.ServiceApplication.IAidlTest /部分省略 public void set(int i) throws and
20、roid.os.RemoteException /implement./ public int get() throws android.os.RemoteException /implement./ /需要在服務(wù)端重寫(xiě)set、get函數(shù),實(shí)現(xiàn)具體操作 public void set(int i) throws android.os.RemoteException; public int get() throws android.os.RemoteException; ,AIDL簡(jiǎn)介,AIDL接口代碼結(jié)構(gòu)如下,可以看出這里采用了COM組件開(kāi)發(fā)的Proxy/Stub結(jié)構(gòu),這種代理設(shè)計(jì)模式多用于遠(yuǎn)
21、程對(duì)象的調(diào)用。,AIDL interface,Proxy,Stub,Service,Activity,Process A,Process B,AIDL使用,MyService.java部分帶啊 通過(guò)匿名類,實(shí)現(xiàn)服務(wù)端(stub端)的方法 private final IAidlTest.Stub binder = new IAidlTest.Stub() Override public void set(int i) throws RemoteException /在這里實(shí)現(xiàn)set方法 Override public int get() throws RemoteException /在這里實(shí)驗(yàn)
22、get方法 ; Override public IBinder onBind(Intent intent) return binder; ,AIDL使用,ServiceApplication.java部分代碼 ServiceConnection mSrcConn = new ServiceConnection() Override public void onServiceConnected(ComponentName name, IBinder service) /這里stub.asInterface其實(shí)就是返回一個(gè)代理(Proxy)對(duì)象 IBinder mBinder = IAidlTes
23、t.Stub.asInterface(service); Override public void onServiceDisconnected(ComponentName name) /省略部分代碼 ;,2.多線程,多線程應(yīng)用,為了提供良好的用戶體驗(yàn),我們必須保證程序有高響應(yīng)性,所以不能在UI線程中進(jìn)行耗時(shí)的計(jì)算或IO操作。 而且,Android操作系統(tǒng)在下面情況下會(huì)強(qiáng)制關(guān)閉程序 UI線程在5秒內(nèi)沒(méi)有響應(yīng) 廣播對(duì)象不能再10秒內(nèi)完成onReceive方法,多線程應(yīng)用,因此我們采用多線程的方法,將大規(guī)模的計(jì)算放在后臺(tái)線程中進(jìn)行計(jì)算,然后將計(jì)算結(jié)果再反映前臺(tái)。例如,在后臺(tái)下載網(wǎng)絡(luò)圖片,下載完成后顯
24、示在屏幕上。,新建用戶線程,Java基礎(chǔ) Thread mThread = new Thread() Override public void run() timeConsumingProcess(); ; mThread.start(),新建用戶線程,但是由于Android操作系統(tǒng)的線程安全機(jī)制,我們不能在非UI線程中重繪UI,所以在用戶線程中進(jìn)行類似更改進(jìn)度條,修改TextView文字等操作都會(huì)造成程序強(qiáng)制關(guān)閉(FC) Android提供了兩種方法解決上述問(wèn)題: Handler AsyncTask,Handler機(jī)制,Android操作系統(tǒng)在UI線程中,缺省維護(hù)這一個(gè)MessageQueue和一個(gè)Looper。 Looper偽碼 While(true) Msg =getFirstMessage(MessageQueue) if(Msg != null) processMessage() ,Handler機(jī)制,Looper通過(guò)一個(gè)死循環(huán),當(dāng)有消息Message加入隊(duì)列時(shí),通過(guò)FIFO的順序處理消息。 一個(gè)Message中包括了處理Message的Handler對(duì)象還有消息內(nèi)容。 這種機(jī)制對(duì)應(yīng)這設(shè)計(jì)模式中的命令模式 Handler與UI線程是同一個(gè)線程,所以我們?cè)谟脩艟€程中完成計(jì)算之后,可以通過(guò)向消息隊(duì)列加入一個(gè)消息,通知特定的Hand
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 油鋸安全操作規(guī)程
- 生態(tài)度假村租賃及服務(wù)協(xié)議范本
- 商業(yè)綜合體場(chǎng)地房屋租賃及全面物業(yè)服務(wù)合同
- 跨境電商采購(gòu)銷售及倉(cāng)儲(chǔ)物流合同
- 餐飲行業(yè)廚師技能培訓(xùn)勞動(dòng)合同模板
- 海洋工程安裝工程保障險(xiǎn)合同
- 水產(chǎn)養(yǎng)殖場(chǎng)場(chǎng)地租賃與養(yǎng)殖服務(wù)合同
- 堰塘漏水排查方案
- 水系清理維護(hù)方案
- 圖形推理面試題及答案
- 新疆警察學(xué)院面試問(wèn)題及答案
- 小學(xué)三到六年級(jí)全冊(cè)單詞默寫(xiě)(素材)-2023-2024學(xué)年譯林版(三起)小學(xué)英語(yǔ)
- 鐵嶺市高校畢業(yè)生“三支一扶”計(jì)劃招募筆試真題2022
- DL-T1474-2021交、直流系統(tǒng)用高壓聚合物絕緣子憎水性測(cè)量及評(píng)估方法
- 水利安全生產(chǎn)風(fēng)險(xiǎn)防控“六項(xiàng)機(jī)制”右江模式經(jīng)驗(yàn)分享
- 天然氣泄漏事故演練方案及評(píng)估
- 《養(yǎng)老機(jī)構(gòu)認(rèn)知障礙照護(hù)專區(qū)設(shè)置與服務(wù)規(guī)范》
- 婦科炎癥健康教育課件
- 兒科護(hù)理學(xué)(高職)全套教學(xué)課件
- 干眼門(mén)診建設(shè)計(jì)劃書(shū)
- MBR膜系統(tǒng)清洗方案
評(píng)論
0/150
提交評(píng)論