一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android App在線程中創(chuàng)建handler的方法講解

 流浪的星星318 2017-02-22

相關概念
1.Handler:可以看做是一個工具類,用來向消息隊列中插入消息的;
2.Thread:所有與Handler相關的功能都是與Thread密不可分的,Handler會與創(chuàng)建時所在的線程綁定;
3.Message:消息;
4.MessageQueue:消息隊列,對消息進行管理,實現(xiàn)了一個Message鏈表;
5.Looper:消息循環(huán),從MessageQueue中取出Message進行處理;
6.HandlerThread:繼承Thread,實例化時自動創(chuàng)建Looper對象,實現(xiàn)一個消息循環(huán)線程.

在Android開發(fā)中經(jīng)常會使用到線程,一想到線程,一般都會想到:

1
new Thread(){...}.start();

這樣的方式。這樣如果在一個Activity中多次調用上面的代碼,那么將創(chuàng)建多個匿名線程,如果這些線程的沒有被銷毀,那肯定會影響性能呢。這個時候我么就想到了android提供的一個異步處理線程的類HandlerThread。

一般Handler的用法

1
Handler handler = new Handler(){...};

這樣創(chuàng)建的handler是在主線程即UI線程下的Handler,即這個Handler是與UI線程下的默認Looper綁定的(當然也只有主線程才能這么干,子線程是干不了的,除非自己創(chuàng)建個looper)。因此,有些時候會占用ui主線程,引起一些問題,所以我們就想到了重新創(chuàng)建個子線程,來處理handler。。。。
使用HandlerThread解決問題

HandlerThread實際上繼承于Thread,只不過它比普通的Thread多了一個Looper。我們可以使用下面的例子創(chuàng)建Handler

1
2
HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();

創(chuàng)建HandlerThread時要把它啟動了,即調用start()方法。

接著就是handler的使用,如下:

1
2
mHandler = new Handler(thread.getLooper());
//TODO:you can post or send something....

創(chuàng)建Handler時將HandlerThread中的looper對象傳入。那么這個mHandler對象就是與HandlerThread這個線程綁定了(這時就不再是與UI線程綁定了,這樣它處理耗時操作將不會阻塞UI)。


線程中消息處理的流程圖

2016324142334101.png (558×479)

消息插入隊列的位置由參數(shù)uptimeMillis來確定。

Handler與線程的關系

2016324142408465.png (556×342)

1.HandlerThread就是一個封裝了Looper的Thread.
2.Handler會與實例化時所在的線程綁定.

UI線程與子線程通信相關

2016324142428965.png (556×325)

1.需要更新UI,則需要使用與主線程綁定的Handler發(fā)送消息,若使用在子線程中創(chuàng)建的Handler則會拋出異常;
2.子線程中實例化Handler對象首先需要調用Looper.prepare(),否則會拋出異常;
3.調用Looper.loop()方法消息循環(huán)才會啟動;
使用Handler時一些需要注意的地方
Looper.prepare(),主線程使用handler,系統(tǒng)默認prepare了,子線程中創(chuàng)建handler必須在前面Looper.prepare(),后面加上Looper.loop();

源碼中:
主線程:
在程序啟動的時候,系統(tǒng)已經(jīng)幫我們自動調用了Looper.prepare()方法。查看ActivityThread中的main()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
  sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
  Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

請注意Looper.prepareMainLooper():

1
2
3
4
5
6
7
public static final void prepareMainLooper() {
prepare();
setMainLooper(myLooper());
if (Process.supportsProcesses()) {
  myLooper().mQueue.mQuitAllowed = false;
}
}

子線程:

1
2
3
4
5
6
7
8
new Thread(new Runnable() {
    @Override
    public void run() {
      Looper.prepare()
      handler2 = new Handler();
      Looper.loop()
    }
  }).start();

如果沒有Looper.prepare().會報錯:

Can't create handler inside thread that has not called Looper.prepare()
因為沒looper對象創(chuàng)建

looper.prepare()源碼:

1
2
3
4
5
6
7
public static final void prepare() {
if (sThreadLocal.get() != null) {
  throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
  

    
   

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本三区不卡高清更新二区| 精品少妇一区二区视频| 中文字幕av诱惑一区二区 | 国产精品超碰在线观看| 亚洲午夜av久久久精品| 小黄片大全欧美一区二区| 青青操视频在线观看国产 | 一区二区三区欧美高清| 99国产高清不卡视频| 亚洲专区一区中文字幕| 日韩一区二区三区在线日| 亚洲一区二区三区av高清| 国产一区二区三区成人精品| 国产成人高清精品尤物| 亚洲一区二区三区三区| 成人免费高清在线一区二区| 国产户外勾引精品露出一区| 国产精品伦一区二区三区四季| 婷婷激情五月天丁香社区| 日韩一区二区三区高清在| 少妇福利视频一区二区| 一区二区福利在线视频| 日本一本在线免费福利| 日韩和欧美的一区二区三区| 欧美日韩精品综合一区| 日韩欧美精品一区二区三区 | 美日韩一区二区精品系列| 又大又长又粗又黄国产| 国产日韩精品激情在线观看| 精品欧美日韩一二三区| 成人国产激情在线视频| 日韩高清一区二区三区四区| 欧美六区视频在线观看| 亚洲精品欧美精品日韩精品| 国产精品一区二区高潮| 又色又爽又黄的三级视频| 欧美在线视频一区观看| 99久久国产精品亚洲| 欧美日韩国产午夜福利| 日韩精品你懂的在线观看| 国产日韩久久精品一区|