成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android:用Handler實(shí)現(xiàn)異步處理功能

移動(dòng)開發(fā) Android
若把一些類似于下載的功能寫在Activity里,會(huì)導(dǎo)致Activity阻塞,長時(shí)間無響應(yīng),直至頁面假死。因此,我們需要把這些耗時(shí)的操作放在單獨(dú)的子線程中操作,這就是Handler的使命。

一.一個(gè)問題

有這樣一個(gè)問題值得我們思考,若把一些類似于下載的功能(既耗時(shí)且不一定有結(jié)果)寫在Activity(主線程)里,會(huì)導(dǎo)致Activity阻塞,長時(shí)間無響應(yīng),直至頁面假死(如果5秒鐘還沒有完成的話,會(huì)收到Android系統(tǒng)的一個(gè)錯(cuò)誤提示 "強(qiáng)制關(guān)閉")。因此,我們需要把這些耗時(shí)的操作放在單獨(dú)的子線程中操作。這就是Handler的使命。Handler提供異步處理的功能,發(fā)送和接收不是同時(shí)的(Activity的主線程和線程隊(duì)列里的線程是不同的線程,并行進(jìn)行,互不影響)。

二.Handler簡介

Handler 為Android操作系統(tǒng)中的線程通信工具,它主要由兩個(gè)作用:(1)安排消息或Runnable 在某個(gè)主線程中某個(gè)地方執(zhí)行(2)安排一個(gè)動(dòng)作在另外的線程中執(zhí)行。每個(gè)Handler對(duì)象維護(hù)兩個(gè)隊(duì)列(FIFO),消息隊(duì)列和Runnable隊(duì)列, 都是有Android操作系統(tǒng)提供的。Handler可以通過這兩個(gè)隊(duì)列來分別:

  1. 發(fā)送、接受、處理消息–消息隊(duì)列;
  2. 啟動(dòng)、結(jié)束、休眠線程–Runnable隊(duì)列;

Handler的使用方法大體分為3個(gè)步驟:1.創(chuàng)建Handler對(duì)象。2.創(chuàng)建Runnable和消息。3.調(diào)用post以及sendMessage方法將Runnable和消息添加到隊(duì)列。

三.Runnable隊(duì)列

1.java中的線程

在java中,線程的創(chuàng)建有兩種方法:繼承Thread類和實(shí)現(xiàn)Runnable接口。而這最重要的都是要復(fù)寫run方法來實(shí)現(xiàn)線程的功能。當(dāng)線程的時(shí)間片到了,開始運(yùn)行時(shí),就執(zhí)行run()函數(shù),執(zhí)行完畢,就進(jìn)入死亡狀態(tài)。

舉個(gè)創(chuàng)建線程的例子:

  1. Runnable r=new Runnable(){ 
  2.  
  3. @Override 
  4. public void run() { 
  5. // TODO Auto-generated method stub 
  6. System.out.println("thread"); 
  7. handler.postDelayed(thread, 3000); 
  8. }; 

2.關(guān)于Runnable隊(duì)列

(1)原理

Android的線程異步處理機(jī)制:Handler對(duì)象維護(hù)一個(gè)線程隊(duì)列,有新的Runnable送來(post())的時(shí)候,把它放在隊(duì)尾,而處理 Runnable的時(shí)候,從隊(duì)頭取出Runnable執(zhí)行。當(dāng)向隊(duì)列發(fā)送一個(gè)Runnable后,立即就返回,并不理會(huì)Runnable是否被執(zhí)行,執(zhí)行 是否成功等。而具體的執(zhí)行則是當(dāng)排隊(duì)排到該Runnable后系統(tǒng)拿來執(zhí)行的。這就好比郵局的例子。寄信者將信寫好后放入郵筒就回家了,他并不知道郵件何 時(shí)被郵局分發(fā),何時(shí)寄到,對(duì)方怎樣讀取這些事。這樣,就實(shí)現(xiàn)了Android的異步處理機(jī)制。

(2)具體操作

向隊(duì)列添加線程:

handler.post(Runnable );將Runnable直接添加入隊(duì)列

handler.postDelayed(Runnable, long)延遲一定時(shí)間后,將Runnable添加入隊(duì)列

handler.postAtTime(Runnable,long)定時(shí)將Runnable添加入隊(duì)列

終止線程:

handler.removeCallbacks(thread);將Runnable從Runnable隊(duì)列中取出

四.消息隊(duì)列

1.消息對(duì)象

(1)Message對(duì)象

Message對(duì)象攜帶數(shù)據(jù),通常它用arg1,arg2來傳遞消息,當(dāng)然它還可以有obj參數(shù),可以攜帶Bundle數(shù)據(jù)。它的特點(diǎn)是系統(tǒng)性能消耗非常少。

初始化: Message msg=handler.obtainMessage();

(2)Bundle對(duì)象

Bundle是Android提供的類,可以把它看做是特殊的Map,即鍵值對(duì)的包。而它特殊在鍵和值都必須要是基本數(shù)據(jù)類型或是基本數(shù)據(jù)類型的數(shù)組(Map的鍵值要求都是對(duì)象),特別的,鍵要求都是String類型。用Message來攜帶Bundle數(shù)據(jù):

放入:msg.setData(Bundle bundle);

取出:msg.getData();

2.關(guān)于消息隊(duì)列

(1)原理

Android的消息異步處理機(jī)制:Handler對(duì)象維護(hù)一個(gè)消息隊(duì)列,有新的消息送來(sendMessage())的時(shí)候,把它放在隊(duì)尾,之后排隊(duì) 到處理該消息的時(shí)候,由主線程的Handler對(duì)象處理(handleMessage())。整個(gè)過程也是異步的,和Runnable隊(duì)列的原理相同。

(2)具體操作:

向隊(duì)列添加Runnable:handler.sendMessage(Message);

將消息發(fā)送到消息隊(duì)列msg.sendToTarget();

延遲一定時(shí)間后,將消息發(fā)送到消息隊(duì)列 handler.sendMessageDelayed(Message,long);

定時(shí)將消息發(fā)送到消息隊(duì)列 handler.sendMessageAtTime(Message,long)

處理消息:

消息的具體處理過程,需要在new Handler對(duì)象時(shí)使用匿名內(nèi)部類重寫Handler的handleMessage(Message msg)方法,如下:

  1. Handler handler=new Handler(){ 
  2.  
  3. @Override 
  4. public void handleMessage(Message msg) { 
  5. // TODO Auto-generated method stub 
  6. 。。。。。。 
  7.  
  8. 。。。。。。 
  9. }; 

五.Handler的兩個(gè)作用

1.安排消息或Runnable 在某個(gè)主線程中某個(gè)地方執(zhí)行

代碼示例:

  1. public class HandlerTestActivity extends Activity { 
  2. private Button start; 
  3. @Override 
  4. protected void onCreate(Bundle savedInstanceState) { 
  5. // TODO Auto-generated method stub 
  6. super.onCreate(savedInstanceState); 
  7. setContentView(R.layout.handlertest); 
  8. start=(Button) findViewById(R.id.start); 
  9. start.setOnClickListener(new startListener()); 
  10.  
  11. System.out.println("Activity Thread:"+Thread.currentThread().getId()); 
  12. Handler handler=new Handler(); 
  13. Runnable thread=new Runnable(){ 
  14.  
  15. @Override 
  16. public void run() { 
  17. // TODO Auto-generated method stub 
  18. System.out.println("HandlerThread:"+Thread.currentThread().getId()); 
  19.  
  20. }; 
  21. class startListener implements OnClickListener{ 
  22.  
  23. @Override 
  24. public void onClick(View v) { 
  25. // TODO Auto-generated method stub 
  26. handler.post(thread); 
  27.  

這個(gè)小程序中,首先程序啟動(dòng),進(jìn)入onCreate(),打印出當(dāng)前線程(即主線程)的ID,之后點(diǎn)擊按鈕start,會(huì)將線程thread添加到線程隊(duì) 列,執(zhí)行線程thread,thread的作用就是打印出當(dāng)前線程的ID。在這個(gè)程序中,我們可以看到通過Handler我們可以實(shí)現(xiàn)安排 Runnable 在某個(gè)主線程中某個(gè)地方執(zhí)行,即作用(1)。

不過這里有個(gè)小小的陷阱,你發(fā)現(xiàn)了嗎?這個(gè)程序看上去似乎實(shí)現(xiàn)了Handler的異步機(jī)制, handler.post(thread)似乎實(shí)現(xiàn)了新啟線程的作用,不過通過執(zhí)行我們發(fā)現(xiàn),兩個(gè)線程的ID相同!也就是說,實(shí)際上thread還是原來 的主線程,由此可見,handler.post()方法并未真正新建線程,只是在原線程上執(zhí)行而已,我們并未實(shí)現(xiàn)異步機(jī)制。

2.安排一個(gè)動(dòng)作在另外的線程中執(zhí)行。

(1)java中標(biāo)準(zhǔn)的創(chuàng)建線程的方法

第一步:

 

  1.  Runnable r=new Runnable(){ 
  2.  
  3. @Override 
  4. public void run() { 
  5. // TODO Auto-generated method stub 
  6. System.out.println("thread"); 
  7. handler.postDelayed(thread, 3000); 
  8. }; 

第二步:

  1. Thread t=new Thread (r); 

第三步:

  1. t.start(); 

若把上面示例程序中的handler.post(thread);語句改成以上形式,通過打印我們可以看到,兩個(gè)ID是不同的,新的線程啟動(dòng)了!

(2)關(guān)于Looper

Looper類用來為線程開啟一個(gè)消息循環(huán),作用是可以循環(huán)的從消息隊(duì)列讀取消息,所以Looper實(shí)際上就是消息隊(duì)列+消息循環(huán)的封裝。每個(gè)線程只能對(duì)應(yīng)一個(gè)Looper,除主線程外,Android中的線程默認(rèn)是沒有開啟Looper的。

通過Handler與Looper交互,Handler可以看做是Looper的接口,用來向指定的Looper發(fā)送消息以及定義處理方法。默認(rèn)情況下Handler會(huì)與其所在線程的Looper綁定,即:

Handler handler=new Handler();等價(jià)于Handler handler=new Handler(Looper.myLooper());

Looper有兩個(gè)主要方法:

Looper.prepare();啟用Looper
Looper.loop(); 讓Looper開始工作,從消息隊(duì)列里取消息,處理消息。

注意:寫在Looper.loop()之后的代碼不會(huì)被執(zhí)行,這個(gè)函數(shù)內(nèi)部應(yīng)該是一個(gè)循環(huán),當(dāng)調(diào)用mHandler.getLooper().quit()后,loop才會(huì)中止,其后的代碼才能得以運(yùn)行。

(3)Handler異步機(jī)制的實(shí)現(xiàn)

Handler是通過HandlerThread 使得子線程與主線程分屬不同線程的。實(shí)際上,HandlerThread 是一個(gè)特殊的線程,它是一個(gè)封裝好Looper的線程,

代碼示例:

  1.  //創(chuàng)建一個(gè)名叫handler_hread的HandlerThread 對(duì)象 
  2. HandlerThread handlerThread=new HandlerThread("handler_hread"); 
  3.  
  4. //開啟handlerThread,在使用handlerThread.getLooper()之前必須先調(diào)用start方法,否則取出的是空 
  5. handlerThread.start(); 
  6.  
  7. //將handler綁定在handlerThread的Looper上,即這個(gè)handler是運(yùn)行在handlerThread線程中的 
  8. myHandler handler=new myHandler(handlerThread.getLooper()); 
  9.  
  10. class myHandler extends Handler{ 
  11. public myHandler(){} 
  12. public myHandler(Looper looper){ 
  13. super(looper); 
  14. @Override 
  15. public void handleMessage(Message msg) { 
  16. // TODO Auto-generated method stub 
  17. System.out.println("Activity Thread:"+Thread.currentThread().getId()); 
  18. }

這樣,就實(shí)現(xiàn)了handler的異步處理機(jī)制,在調(diào)用handler.post()方法,通過打印線程ID可以得知,子線程與主線程是分屬不同線程的。

責(zé)任編輯:徐川 來源: OSChina
相關(guān)推薦

2017-01-03 17:57:46

Android異步精髓Handler

2010-12-01 14:34:59

AsyncTask異步處理任務(wù)Android

2011-11-23 09:33:45

HandlerLooperMessage

2013-06-27 11:16:27

Android異步加載

2009-07-03 09:44:39

實(shí)現(xiàn)RSS功能JSP技術(shù)

2024-12-24 08:44:55

ActiveMQRabbitMQ交換機(jī)

2013-01-21 13:18:26

IBMdW

2014-05-22 15:00:16

Android消息處理機(jī)制Looper

2014-05-22 15:04:00

Android消息處理機(jī)制Looper

2014-05-22 15:07:44

Android消息處理機(jī)制Looper

2014-05-22 15:38:27

Android消息處理機(jī)制Looper

2014-05-22 15:48:50

Android消息處理機(jī)制Looper

2014-05-22 15:41:59

Android消息處理機(jī)制Looper

2014-05-22 14:57:28

Android消息處理機(jī)制Looper

2014-05-22 15:15:53

Android消息處理機(jī)制Looper

2014-05-22 15:18:25

Android消息處理機(jī)制Looper

2014-05-22 15:33:31

Android消息處理機(jī)制Looper

2014-05-22 15:45:58

Android消息處理機(jī)制Looper

2011-11-23 09:54:32

AndroidAlarm

2009-06-18 11:07:17

Spring fram
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日本电影韩国电影免费观看 | 亚洲免费在线播放 | 青青草视频网 | www.黄色网 | 国产视频精品视频 | 久久国产精品久久久久久久久久 | 毛片一区二区 | 日韩在线不卡 | wwwsihu | 日韩精品一区二区三区四区 | 免费在线国产视频 | 欧美人人| 亚洲成人一区 | 国产成人免费视频网站高清观看视频 | 成人在线视频观看 | 日韩欧美国产一区二区三区 | 国产成人精品一区二 | 91人人澡人人爽 | 99re在线视频 | yiren22综合网成人 | 久久不卡 | 日韩高清国产一区在线 | 国产精品视频一区二区三区 | 亚洲一区二区三区免费在线 | 久久免费大片 | 黄色av网站在线免费观看 | 欧美日韩在线免费 | 国产日韩一区二区 | 国产二区精品视频 | 久久久精品一区 | 伦理二区 | 九九综合 | 一区二区三区四区不卡 | 99久久视频 | 亚洲福利网站 | 中国一级特黄视频 | 久久久视 | 日本福利一区 | 91精品久久| 亚洲精品久久 | 欧洲色|