最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android開發(fā)中Looper.prepare()和Looper.loop()

 更新時(shí)間:2016年11月12日 11:18:55   作者:屌絲迷途  
Looper用于封裝了android線程中的消息循環(huán),默認(rèn)情況下一個(gè)線程是不存在消息循環(huán)(message loop)的,具體調(diào)用方法大家可以通過本文學(xué)習(xí)

什么時(shí)候需要 Looper

  Looper用于封裝了android線程中的消息循環(huán),默認(rèn)情況下一個(gè)線程是不存在消息循環(huán)(message loop)的,需要調(diào)用Looper.prepare()來給線程創(chuàng)建一個(gè)消息循環(huán),調(diào)用Looper.loop()來使消息循環(huán)起作用,使用Looper.prepare()和Looper.loop()創(chuàng)建了消息隊(duì)列就可以讓消息處理在該線程中完成。

使用Looper需要注意什么

  寫在Looper.loop()之后的代碼不會被立即執(zhí)行,當(dāng)調(diào)用后mHandler.getLooper().quit()后,loop才會中止,其后的代碼才能得以運(yùn)行。Looper對象通過MessageQueue來存放消息和事件。一個(gè)線程只能有一個(gè)Looper,對應(yīng)一個(gè)MessageQueue。

比如下面的代碼,只要調(diào)用了getLooper().quit()后代碼2才會執(zhí)行。

class LooperThread extends Thread
{
4 public void run() 
{
Looper.prepare();
//代碼1....
Looper.loop();
//代碼2....
} 
}

警惕線程未終止造成的內(nèi)存泄露;譬如在Activity中關(guān)聯(lián)了一個(gè)生命周期超過Activity的Thread,在退出Activity時(shí)切記結(jié)束線程。一個(gè)典型的例子就是HandlerThread的run方法是一個(gè)死循環(huán),它不會自己結(jié)束,線程的生命周期超過了Activity生命周期,我們必須手動在Activity的銷毀方法中中調(diào)運(yùn)thread.getLooper().quit();才不會泄露。

Looper與Activity

Activity的MainUI線程默認(rèn)是有消息隊(duì)列的。所以在Activity中新建Handler時(shí),不需要先調(diào)用Looper.prepare()

主線程中的Looper.loop()一直無限循環(huán)為什么不會造成ANR

ActivityThread.java 是主線程入口的類,這里你可以看到寫Java程序中司空見慣的main方法,而main方法正是整個(gè)Java程序的入口。

ActivityThread源碼

public static final void main(String[] args) {
...
//創(chuàng)建Looper和MessageQueue
Looper.prepareMainLooper();
...
//輪詢器開始輪詢
Looper.loop();
...
}

Looper.loop()方法

while (true) {
//取出消息隊(duì)列的消息,可能會阻塞
Message msg = queue.next(); // might block
...
//解析消息,分發(fā)消息
msg.target.dispatchMessage(msg);
...
}

ActivityThread的main方法主要就是做消息循環(huán),一旦退出消息循環(huán),那么你的應(yīng)用也就退出了。那為什么這個(gè)死循環(huán)不會造成ANR異常呢?

因?yàn)锳ndroid 的是由事件驅(qū)動的,looper.loop() 不斷地接收事件、處理事件,每一個(gè)點(diǎn)擊觸摸或者說Activity的生命周期都是運(yùn)行在 Looper.loop() 的控制之下,如果它停止了,應(yīng)用也就停止了。只能是某一個(gè)消息或者說對消息的處理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。也就說我們的代碼其實(shí)就是在這個(gè)循環(huán)里面去執(zhí)行的,當(dāng)然不會阻塞了。

handleMessage方法部分源碼

public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord) msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder) msg.obj, false, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case PAUSE_ACTIVITY_FINISHING:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder) msg.obj, true, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 1) != 0);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...........
}
}

可以看見Activity的生命周期都是依靠主線程的Looper.loop,當(dāng)收到不同Message時(shí)則采用相應(yīng)措施。

如果某個(gè)消息處理時(shí)間過長,比如你在onCreate(),onResume()里面處理耗時(shí)操作,那么下一次的消息比如用戶的點(diǎn)擊事件不能處理了,整個(gè)循環(huán)就會產(chǎn)生卡頓,時(shí)間一長就成了ANR。

相關(guān)文章

  • Android開發(fā)之自定義UI組件詳解

    Android開發(fā)之自定義UI組件詳解

    這篇文章主要給大家介紹了關(guān)于Android開發(fā)之自定義UI組件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • android使用FlipAnimation實(shí)現(xiàn)3D垂直翻轉(zhuǎn)動畫

    android使用FlipAnimation實(shí)現(xiàn)3D垂直翻轉(zhuǎn)動畫

    這篇文章主要為大家詳細(xì)介紹了android使用FlipAnimation實(shí)現(xiàn)3D垂直翻轉(zhuǎn)動畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 五分鐘教你Android-Kotlin項(xiàng)目編寫

    五分鐘教你Android-Kotlin項(xiàng)目編寫

    本篇文章主要介紹了五分鐘教你Android-Kotlin項(xiàng)目編寫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Android Studio實(shí)現(xiàn)簡易計(jì)算器

    Android Studio實(shí)現(xiàn)簡易計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Android Studio實(shí)現(xiàn)簡易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Android View如何測量

    Android View如何測量

    這篇文章主要為大家介紹了Android View如何進(jìn)行測量,本文為大家介紹view的測量方法,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例

    Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例

    下面小編就為大家分享一篇Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Android中ArrayList和數(shù)組相互轉(zhuǎn)換

    Android中ArrayList和數(shù)組相互轉(zhuǎn)換

    在我們?nèi)粘i_發(fā)中難免會要將ArrayList和數(shù)組相互轉(zhuǎn)換,那么如何才能相互轉(zhuǎn)換呢?下面跟著小編一起通過這篇文章學(xué)習(xí)學(xué)習(xí)。
    2016-08-08
  • Android短信操作常見協(xié)議和常用代碼

    Android短信操作常見協(xié)議和常用代碼

    這篇文章主要介紹了Android短信操作常見協(xié)議和常用代碼,本文直接給出代碼實(shí)例,需要的朋友可以參考下
    2015-04-04
  • Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity

    Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity

    這篇文章主要介紹了Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity,本文是上一篇的補(bǔ)充,需要的朋友可以參考下
    2015-04-04
  • android Chronometer控件使用大全

    android Chronometer控件使用大全

    Chronometer是一個(gè)簡單的計(jì)時(shí)器,這篇文章主要介紹了android Chronometer控件簡單使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09

最新評論

鹤山市| 泉州市| 黑龙江省| 酒泉市| 延安市| 岳阳市| 聊城市| 凌源市| 普定县| 海淀区| 宁陵县| 都兰县| 北海市| 新龙县| 兴化市| 玉山县| 珠海市| 叶城县| 赞皇县| 安福县| 双鸭山市| 罗田县| 重庆市| 日喀则市| 汝阳县| 大渡口区| 阿勒泰市| 盱眙县| 竹北市| 宁蒗| 芮城县| 阿拉善左旗| 宣威市| 建湖县| 镇巴县| 青冈县| 固原市| 虎林市| 民勤县| 新巴尔虎右旗| 莱州市|