日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Handler消息传递机制(一)

發布時間:2025/3/20 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Handler消息传递机制(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么要用Handler:

出于性能優化考慮,Android的UI操作并不是線程安全的,這意味著如果有多個線程并發操作UI組件,可能導致線程安全問題。為了解決這個問題,Android制定了一條簡單的原則:只允許UI線程(亦即主線程)修改Activity中的UI組件。
當一個程序第一次啟動時,Android會同時啟動一條主線程,主線程主要負責處理與UI相關的事件,如用戶的按鍵事件、用戶接觸屏幕的事件、屏幕繪圖事件,并把相關的事件分發到相應的組件進行處理,所以主線程通常又叫做UI線程。

Handler的概念:

1)執行計劃任務,可以在預定的時間執行某些任務,可以模擬定時器
2)線程間通信
在Android的應用啟動時,會創建一個主線程,主線程會創建一個

消息隊列來處理各種消息。當你創建子線程時,你可以在你的子線程中拿到父線程中
創建的Handler 對象,就可以通過該對象向父線程的消息隊列發送消息了
。由于Android要求在UI線程中更新界面,因此,可以通過該方法在其它線程中更新界面。

Handler類包含如下方法用于發送、處理消息:

? void handlerMessage(Message msg):處理消息的方法,該方法通常用于被重寫。
   ? final boolean hasMessage(int what):檢查消息隊列中是否包含what屬性為指定值的消息。
? sendEmptyMessage(int what):發送空消息
? final boolean sendMessage(Message msg):立即發送消息,注意這塊返回值,如果message成功的被放到message queue里面則返回true,反之,返回false;(個人建議:對于這類問題不必主觀去記它,當實際使用時,直接查看源碼即可,源碼中有詳細的注釋)

Handler的作用:
(1)在一個線程中發送消息。
(2)在另一個線程中獲取、處理消息。
Handler處理的基本原理:

為了讓主線程能及時處理子線程發送的消息,顯然只能通過回調的方法來實現----開發者只要重寫Handler類中的方法,當新啟動的線程發送消息時,消息會發送至與之關聯的MessageQueue,而Handler會不斷的從MessageQuere中獲取并處理消息-----這將導致Handler類中處理消息的方法被回調。
在線程中使用Handler的基本步驟如下
在被調用線程中完成以下內容:
(1)調用 Looper的prepare()方法為當前線程創建Looper對象,創建Looper對象時,它的構造器會創建與之配套的MessageQueue。
(2)有了Looper之后,創建Handler子類的實例,重寫HandlerMessage()方法,該方法負責處理來自其它線程的消息。
(3)調用Looper的loop()方法啟動Looper。

注:若被調用線程是主線程類,由于系統自動為主線程創建了Looper的實例,因此第一、三步驟可省略,而只需要做第2步即可。
在調用線程中完成:
(1)創建message,并填充內容。
(2)使用被調用類創建的Handler實例,調用sendMessage(Message msg)方法。

Handler 與線程的關系
Handler 一般運行于主線程內,也可以運行在子線程中,但是一定要創建Looper對象。主線程中Android已經為之創建了Looper對象


使用Handler的兩種常見情況:
1、只能在主UI中修改UI。但實際上,有部分UI需要在子線程中控制其修改邏輯,因此子線程需要通過handler通知主線程修改UI。這在游戲開發中尤其常見,比如需要讓新啟動的線程周期性的改變UI。、

子線程通知主UI線程修改UI組件的例子,新線程周期性的修改ImageView所顯示的圖片:

這個例子是Handler在主線程中獲取,處理消息,在子線程中發送消息

public class HandlerTest extends Activity {// 定義周期性顯示的圖片的IDint[] imageIds = new int[]{R.drawable.java,R.drawable.ee,R.drawable.ajax,R.drawable.xml,R.drawable.classic};int currentImageId = 0;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);final ImageView show = (ImageView) findViewById(R.id.show);final Handler myHandler = new Handler()//在主線程中,獲取,處理消息,更新UI組件,可以修改UI組件{@Overridepublic void handleMessage(Message msg){// 如果該消息是本程序所發送的if (msg.what == 0x1233){// 動態地修改所顯示的圖片show.setImageResource(imageIds[currentImageId++% imageIds.length]);}}};// 定義一個計時器,讓該計時器周期性地執行指定任務。子線程通知主線程修改UI組件,實現進程間通信new Timer().schedule(new TimerTask(){@Overridepublic void run(){// 發送空消息myHandler.sendEmptyMessage(0x1233);在線程中發送消息}}, 0, 1200);} }
2、為避免ANR,應該在子線程中執行耗時較長的操作,而此操作完成后,有可能需要通知主線程修改UI

在子線程中執行耗時任務后,通知主線程修改UI組件的例子:使用新進程計算質數,并用Toast顯示

這個例子是在主線程中發送消息,在子線程中獲取,處理消息

public class CalPrime extends Activity {static final String UPPER_NUM = "upper";EditText etNum;CalThread calThread;// 定義一個線程類class CalThread extends Thread{public Handler mHandler;public void run(){Looper.prepare();//創建Looper對象,每個線程使用Handler時都要有一個Looper對象mHandler = new Handler()//在子線程中用handler獲取,處理消息{// 定義處理消息的方法@Overridepublic void handleMessage(Message msg){if(msg.what == 0x123){int upper = msg.getData().getInt(UPPER_NUM);List<Integer> nums = new ArrayList<Integer>();// 計算從2開始、到upper的所有質數outer:for (int i = 2 ; i <= upper ; i++){// 用i處于從2開始、到i的平方根的所有數for (int j = 2 ; j <= Math.sqrt(i) ; j++){// 如果可以整除,表明這個數不是質數if(i != 2 && i % j == 0){continue outer;}}nums.add(i);}// 使用Toast顯示統計出來的所有質數Toast.makeText(CalPrime.this , nums.toString(), Toast.LENGTH_LONG).show();}}};Looper.loop();//啟動Looper}}@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);etNum = (EditText)findViewById(R.id.etNum);calThread = new CalThread();// 啟動新線程calThread.start();}// 為按鈕的點擊事件提供事件處理函數public void cal(View source){// 創建消息Message msg = new Message();msg.what = 0x123;Bundle bundle = new Bundle();bundle.putInt(UPPER_NUM ,Integer.parseInt(etNum.getText().toString()));msg.setData(bundle);// 在主線程中向新線程中的Handler發送消息calThread.mHandler.sendMessage(msg);//在主線程中發送消息} }










總結

以上是生活随笔為你收集整理的Handler消息传递机制(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。