Android初識(shí)多線程

Android多線程

  • 一個(gè)Android的應(yīng)用程序運(yùn)行在一個(gè)獨(dú)立的進(jìn)程中碍讨,運(yùn)行在一個(gè)獨(dú)立的虛擬機(jī)(dvk)上。 (進(jìn)程名為包名)

  • Android應(yīng)用程序開啟后鸟顺,默認(rèn)開啟一個(gè)主線程(UI線程)
    Activity次坡,Service疼约,BroadcastReceiver組件運(yùn)行在主線程中
    Android應(yīng)用程序退出后溺拱,保留空UI線程逃贝,可以加快應(yīng)用程序啟動(dòng)速度

  • 用戶不能在UI主線程中做耗時(shí)的操作,一旦該操作超過5s迫摔,應(yīng)用程序拋一個(gè)ANR異常(Application not respond)沐扳。
    如何避免ANR錯(cuò)誤?
    將耗時(shí)的操作放入子線程中句占。(耗時(shí)的操作包括:長(zhǎng)時(shí)間的休眠沪摄,計(jì)數(shù),聯(lián)網(wǎng)辖众,復(fù)雜的運(yùn)算卓起。)

  • 只有主線程才能操作Widget控件。
    如果在子線程中操作Widget控件凹炸,系統(tǒng)拋出CalledFromWrongThreadException異常。

  • 系統(tǒng)為什么要這么做昼弟?
    避免出現(xiàn)同步問題啤它。

Handler機(jī)制。

  • Goolge為什么設(shè)計(jì)這套機(jī)制舱痘?
    主要是為了解決非UI線程中不能更新Widget控件的問題

  • Handler機(jī)制剖析
    子線程發(fā)送消息給底層的消息隊(duì)列变骡。
    handler.sendMessage(msg)
    主線程查詢消息隊(duì)列,處理消息對(duì)象芭逝。
    handlerMessage(msg)
    MessageQueue 消息隊(duì)列
    負(fù)責(zé)存儲(chǔ)消息對(duì)象

  • Looper
    給UI線程安排代碼塌碌,一個(gè)UI線程只能有一個(gè)Looper對(duì)象,否則多個(gè)Looper對(duì)象都在UI線程上安排代碼旬盯,解決沖突就是個(gè)大問題台妆。 Looper對(duì)象會(huì)線性安排在UI線程上執(zhí)行的代碼,它通過一個(gè)隊(duì)列管理各個(gè)Handler對(duì)象提交的代碼胖翰。

  • Message消息對(duì)象

//從消息池中獲取消息對(duì)象
Message msg = handler.obtainMessage();
//在消息對(duì)象上綁定int類型數(shù)據(jù)
msg.arg1 = count;
//在消息對(duì)象上綁定其它類型數(shù)據(jù)
msg.setData(Bundle);        //Bundler為數(shù)據(jù)集(類似于HashMap容器)
  • 向消息隊(duì)列發(fā)送消息接剩,1000毫秒后執(zhí)行Runnable對(duì)象中的代碼。
myHandler.postDelayed(new Runnable() { 
           @Override 
          public void run() { 
                 // TODO Auto-generated method stub 
                 Log.e("Test", "thread name = "+Thread.currentThread().getName());
           }
}萨咳, 1000);

異步任務(wù)(AsyncTask)

  • 概念
    封裝多線程和Handler機(jī)制懊缺。給用戶提供重寫接口的方式,不需要用戶手動(dòng)創(chuàng)建子線程和Handler對(duì)象培他。

  • 異步任務(wù)的優(yōu)點(diǎn)
    Handler模式需要為每一個(gè)任務(wù)創(chuàng)建一個(gè)新的線程鹃两,任務(wù)完成后通過Handler實(shí)例向UI主線程發(fā)送消息遗座,完成界面的更新,這種方式對(duì)于整個(gè)過程的控制比較精細(xì)俊扳,但是也有缺點(diǎn)途蒋,代碼臃腫,在多個(gè)任務(wù)同時(shí)執(zhí)行時(shí)拣度,不易對(duì)線程進(jìn)行精確的控制碎绎。為了簡(jiǎn)化操作,Android1.5提供了一個(gè)工具類AsyncTask抗果,它是創(chuàng)建異步任務(wù)變的更加簡(jiǎn)單筋帖,不再需要編寫任務(wù)線程和Handler實(shí)例就可完成任務(wù)。

  • 異步任務(wù)的局限性
    多個(gè)異步任務(wù)不能同時(shí)執(zhí)行冤馏,在某個(gè)時(shí)間內(nèi)日麸,只能執(zhí)行一個(gè)異步任務(wù)。

  • 執(zhí)行異步任務(wù)的步驟:

  1. execute(Params... params)逮光,執(zhí)行一個(gè)異步任務(wù)代箭,需要我們?cè)诖a中調(diào)用此方法,觸發(fā)異步任務(wù)的執(zhí)行涕刚。
  2. onPreExecute()嗡综,在execute(Params... params)被調(diào)用后立即執(zhí)行,一般用來在執(zhí)行后臺(tái)任務(wù)前對(duì)UI做一些標(biāo)記杜漠。
  3. doInBackground(Params... params)极景,在onPreExecute()完成后立即執(zhí)行,用于執(zhí)行較為費(fèi)時(shí)的操作驾茴,此方法將接收輸入?yún)?shù)和返回計(jì)算結(jié)果盼樟。在執(zhí)行過程中可以調(diào)publishProgress(Progress... values)來更新進(jìn)度信息。
  4. onProgressUpdate(Progress... values)锈至,在調(diào)用publishProgress(Progress... values)時(shí)晨缴,此方法被執(zhí)行,直接將進(jìn)度信息更新到UI組件上峡捡。
  5. onPostExecute(Result result)击碗,當(dāng)后臺(tái)操作結(jié)束時(shí),此方法將會(huì)被調(diào)用棋返,計(jì)算結(jié)果將做為參數(shù)傳遞到此方法中延都,直接將結(jié)果顯示到UI組件上。
  • 取消異步任務(wù)
/** 
*cancel(true) 取消當(dāng)前的異步任務(wù)睛竣,傳入的true,表示當(dāng)中斷異步任務(wù)時(shí)繼續(xù)已經(jīng)運(yùn)行的線程的操作晰房, 
*但是為了線程的安全一般為讓它繼續(xù)設(shè)為true 
**/ 
mTask.cancel(true); 
/** 
* 但是重新運(yùn)行后會(huì)發(fā)現(xiàn)還是不能起到效果, 
* 注意:這是因?yàn)閏ancel方法只是發(fā)出一個(gè)請(qǐng)求取消異步任務(wù)的信號(hào), 
* 將對(duì)應(yīng)當(dāng)前的異步任務(wù)標(biāo)記為CANCEL狀態(tài),而并不是真正取消線程的執(zhí)行殊者,
 * 而此時(shí)異步任務(wù)中的線程仍然在執(zhí)行并沒有結(jié)束 
* 所以效果依然是這樣的与境,并且在java中我們是無法直接暴力將一個(gè)線程給停止掉
 * 既然我們知道無法去取消一個(gè)已經(jīng)正在運(yùn)行的線程,但是我們?nèi)绾稳ソ鉀Q這個(gè)BUG呢猖吴? 
* 在異步任務(wù)中還給我們提供一個(gè)isCanceled的回調(diào)方法摔刁,也就是當(dāng)我已經(jīng)給當(dāng)前的異步任務(wù) 
* 調(diào)用了cancel(true)方法,發(fā)出一個(gè)請(qǐng)求取消異步任務(wù)的信號(hào)海蔽,那么此時(shí)的isCanceled的回調(diào)方法 
* 會(huì)直接返回一個(gè)true共屈,那么我們就可以通過判斷當(dāng)前異步任務(wù)isCanceled是否為true,來終止
* 線程中的操作而不是去終止線程党窜,從而達(dá)到了界面顯示好像線程中的操作被終止了拗引,而實(shí)際上 
* 該線程依然在運(yùn)行
* */
  • 注意
  1. 異步任務(wù)對(duì)象只能執(zhí)行一次。
  2. 異步任務(wù)對(duì)象必須在UI主線程中創(chuàng)建幌衣。execute(Params... params)方法必須在UI線程中調(diào)用矾削。
  3. 不要手動(dòng)調(diào)用onPreExecute(),doInBackground(Params... params)豁护,onProgressUpdate(Progress... values)哼凯,onPostExecute(Result result)這幾個(gè)方法。
  4. 不能在doInBackground(Params... params)中更改UI組件的信息楚里。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末断部,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子班缎,更是在濱河造成了極大的恐慌家坎,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吝梅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惹骂,警方通過查閱死者的電腦和手機(jī)苏携,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來对粪,“玉大人右冻,你說我怎么就攤上這事≈茫” “怎么了纱扭?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)儡遮。 經(jīng)常有香客問我乳蛾,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任肃叶,我火速辦了婚禮蹂随,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘因惭。我一直安慰自己岳锁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布蹦魔。 她就那樣靜靜地躺著激率,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勿决。 梳的紋絲不亂的頭發(fā)上乒躺,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音剥险,去河邊找鬼聪蘸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛表制,可吹牛的內(nèi)容都是我干的健爬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼么介,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼娜遵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起壤短,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤设拟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后久脯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纳胧,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年帘撰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跑慕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摧找,死狀恐怖核行,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹬耘,我是刑警寧澤芝雪,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站综苔,受9級(jí)特大地震影響惩系,放射性物質(zhì)發(fā)生泄漏位岔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一蛆挫、第九天 我趴在偏房一處隱蔽的房頂上張望赃承。 院中可真熱鬧,春花似錦悴侵、人聲如沸瞧剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抓于。三九已至,卻和暖如春浇借,著一層夾襖步出監(jiān)牢的瞬間捉撮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工妇垢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巾遭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓闯估,卻偏偏與公主長(zhǎng)得像灼舍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涨薪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容