開始前的話
啃找到的那兩本好書浮禾,有些收獲交胚。不過(guò)這周我時(shí)間是在太趕,下周的My Android Series
系列再開坑寫那些安卓底層盈电、開發(fā)技巧的東西蝴簇。
這篇博文,我打算寫寫多線程匆帚、網(wǎng)絡(luò)和藍(lán)牙熬词,一直以來(lái)自己對(duì)網(wǎng)絡(luò)開發(fā)和多線程的掌握一直都不太好,也缺少開發(fā)實(shí)踐吸重;藍(lán)牙則是這次寫項(xiàng)目要用到荡澎,粗略看了下資料發(fā)現(xiàn)藍(lán)牙和socket編程十分相似均践,所以也放到一塊來(lái)說(shuō)。
(好像這樣的話一篇博文會(huì)特別長(zhǎng)摩幔,我還是分成三篇來(lái)寫吧——多線程+Service、網(wǎng)絡(luò)鞭铆、藍(lán)牙)
Android中的多線程 及 Service(服務(wù))
這里先說(shuō)一下多線程和異步消息處理機(jī)制或衡,因?yàn)镾ervice是
Android 多線程 和 異步消息處理機(jī)制
多線程
andorid
中的多線程和Java十分類似,語(yǔ)法都基本一樣车遂。
- 繼承Thread
class MyThread extends Thread{
@Override
public void run(){
//具體邏輯
}
}
然后要用的時(shí)候 new一個(gè)MyThread實(shí)例封断,調(diào)用start()方法就ok
new MyThread().start();
- 實(shí)現(xiàn)Runnable
class MyThread implements Runnable{
@Override
public void run(){
//具體邏輯
}
}
啟動(dòng)線程的時(shí)候要改一下。使用Thread的構(gòu)造函數(shù)接收一個(gè)Runnable參數(shù)舶担,這里就是new出的MyThread對(duì)象坡疼;然后再調(diào)用Thread的start方法
MyThread myThread = new MyThread();
new Thread(myThread).start();
- anroid 中一些需要注意的東西
- 無(wú)論何時(shí)啟動(dòng)APP,所有的組件都會(huì)運(yùn)行在一個(gè)單獨(dú)的線程中(默認(rèn)的)——叫做主線程衣陶。這個(gè)線程主要用于處理UI的操作并為視圖組件和小部件分發(fā)事件等柄瑰,因此主線程也被稱作UI線程。
- 如果你在UI線程中運(yùn)行一個(gè)耗時(shí)操作剪况,那么UI就會(huì)被鎖住教沾,直到這個(gè)耗時(shí)操作結(jié)束。這是很不友好的用戶體驗(yàn)設(shè)計(jì)译断,這就是為什么要把一些復(fù)雜的工作移動(dòng)到其它的線程中去執(zhí)行授翻。如果你在UI線程中運(yùn)行一個(gè)耗時(shí)的任務(wù),那么很有可能會(huì)發(fā)生ANR(應(yīng)用無(wú)響應(yīng))孙咪,這樣用戶就會(huì)很快地結(jié)束掉你的APP堪唐。
這個(gè)部分我會(huì)在之后的深入研究Android機(jī)制中進(jìn)行更為詳細(xì)的學(xué)習(xí)分析,這里做個(gè)標(biāo)記~
異步消息處理
之所以會(huì)有異步消息處理機(jī)制翎蹈,就我個(gè)人的理解淮菠,是由于耗時(shí)操作雖然可以新開一個(gè)線程來(lái)處理,不過(guò)如果處理的結(jié)果對(duì)UI更新這樣的操作杨蛋,就會(huì)阻塞主線程兜材。
根據(jù)操作系統(tǒng)的知識(shí),異步機(jī)制就意味著我們不用阻塞在那些耗時(shí)的操作上逞力,只需要發(fā)出一個(gè)耗時(shí)操作的請(qǐng)求就可以做接下來(lái)的事情曙寡,這樣,就不會(huì)發(fā)生進(jìn)程的阻塞寇荧。等到耗時(shí)操作完成之后會(huì)用特定的方式來(lái)通知我們举庶,已經(jīng)完成
-
Android中的異步消息處理主要包括四個(gè)部分:
Message, Handler, MessageQueue, Looper
之前看的Android面試題目也有很多問(wèn)道這部分的,足見重要性揩抡,繼續(xù)說(shuō)户侥。
- handler : 是整個(gè)異步消息處理機(jī)制中的控制者镀琉,處理者。它負(fù)責(zé)發(fā)送和處理消息
- message : 主要是在不同的線程之間傳遞消息蕊唐,作為一個(gè)消息的載體屋摔,其中的what字段等等,可以攜帶一定的數(shù)據(jù)信息替梨。
- MessageQueue: 消息隊(duì)列钓试,整個(gè)程序可能有很多異步消息需要處理,但 是對(duì)于一個(gè)線程來(lái)說(shuō)(主線程),只能有一個(gè)handler 副瀑,MessageQueue弓熏。所以我們需要把還沒有處理的消息放入消息隊(duì)列當(dāng)中糠睡。
- looper:它相當(dāng)于MessageQueue中的調(diào)度者,通過(guò)調(diào)用loop方法狈孔,進(jìn)行一個(gè)無(wú)限循環(huán),不斷的從消息隊(duì)列中取出消息除抛,發(fā)送給handler進(jìn)行處理。 上面的代碼大家也看到了到忽,我要做的是兩件事橄教,一個(gè)是要進(jìn)行一個(gè)循環(huán)耗時(shí)操作喘漏,還有一個(gè)就是更新textview控件上面的內(nèi)容。耗時(shí)操作是必須放在子線程中的持灰,但是對(duì)UI的操作寫到了一個(gè)handlemessage的函數(shù)中负饲。
這張圖片摘自郭霖大神的第一行代碼第九章
這個(gè)部分我的理解還不夠深刻,之后有空可以重新填一下這個(gè)坑
- 總結(jié)一下異步消息處理機(jī)制的過(guò)程返十。
- 首先需要在主線程中創(chuàng)建一個(gè)Handler對(duì)象洞坑,并重寫handleMessage()方法盲链。
當(dāng)子線程中需要進(jìn)行UI操作,就創(chuàng)建一個(gè)Message對(duì)象火架,并通過(guò)Handler將這條消息發(fā)送出去。
之后何鸡,指條消息就被添加到MessageQueue的隊(duì)列中等待被處理,而Looper則會(huì)一直嘗試從MessageQueue中取出待處理的消息牛欢,最后分發(fā)回Handler的handlerMessage()方法骡男。
由于Handler是在主線程中創(chuàng)建的,所以此時(shí)handleMessage()方法中的代碼也會(huì)在主線程中運(yùn)行傍睹,也就可以進(jìn)行UI操作了隔盛。
使用AsyncTask
這個(gè)部分我先跳過(guò),創(chuàng)新杯回來(lái)再寫
Service
什么是服務(wù)
Service是android 系統(tǒng)中的四大組件之一(Activity拾稳、Service吮炕、BroadcastReceiver、ContentProvider)访得,它跟Activity的級(jí)別差不多龙亲,但不能自己運(yùn)行只能后臺(tái)運(yùn)行,并且可以和其他組件進(jìn)行交互悍抑。service可以在很多場(chǎng)合的應(yīng)用中使用鳄炉,比如播放多媒體的時(shí)候用戶啟動(dòng)了其他Activity這個(gè)時(shí)候程序要在后臺(tái)繼續(xù)播放,比如檢測(cè)SD卡上文件的變化搜骡,再或者在后臺(tái)記錄你地理信息位置的改變等等拂盯,總之服務(wù)總是藏在后臺(tái)的。
Service的啟動(dòng)有兩種方式:**context.startService() **和 context.bindService()這里放上
Google
給Service的定義
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
15:20 這個(gè)部分先寫到這里记靡,先去寫會(huì)兒代碼