Android消息機制
·Android不可避免要操作一些耗時操作
·主線程堵塞影響用戶交互,需要運行完后通知主線程更新
·下面我們來了解下Android的消息機制

在主線程創建完成后系統會默認的創建一個looper對象,他就是個循環操作,循環的讀取系統為主線程創建 好的 Message Queue中的消息(Messa Queue 中存放著許多的MSg),當looper讀取到一個消息時候會為這個消息進行操作處理,當對應的處理執行完成后消息(msg)會被移除出消息隊列(Message Queue),依次循環。
Message與Handler
那么我們在開發過程中遇到的耗時操作是如何處理的呢?
· 這里就用到handle了,首先Handle 對象調用sendMessage 向我們的Messagequeue里面插入一條消息。
· 當looper讀取到這條消息的時候,looper又調用Handler的對象來調用 dispartchMessage 和handleMessage,
值得注意的是 dispatchMessage通常是系統使用的,我們自己定義的Messag消息處理通常是利用 handleMessage
· 對消息隊列的響應操作只能通過Handle來進行,主線的looper發現MessageQueue改變就回去響應消息
· 那個Handle發的消息就有那個handle來響應

·Handler中的常用方法:


簡單的例子:
package com.example.chenzhu.myPRojectblog;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MyHandleActivity extends AppCompatActivity { Handler handler = new Handler(){ //接受消息并且處理消息 @Override public void handleMessage(Message msg) { super.handleMessage(msg); Toast.makeText(MyHandleActivity.this, "handle Message What="+msg.what, Toast.LENGTH_SHORT).show(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_handle); Button button = (Button)findViewById(R.id.sendHandle); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Message msg = new Message();//建立一個消息 msg.what=1; handler.sendMessage(msg);//發送一個消息 } }); }}Thread與Handler
然而在主線程,如果looper在messagequeue里面讀取到一個耗時操作或者死循環消息,然后還是會交給Handle 對象調用dispatchMessage來處理這個消息。而此時我們在次通過Handle 網MessageQueue里面發送一條消息 Looper讀取到后有交給Handle對象處理,而此時系統還在處理上一個耗時操作。那么會怎樣呢?? 著名的ANR就來了,所以我們可以得到一下結論。
· Handler的sendMessage可以在其他線程中運行(本身并不需要刷新界面,只需要發送消息)
· 耗時操作又必須在其他線程中運行。
· 所以耗時操作在子線程完成后通過handle發送message通知主線程來完成UI線程更新UI。
我們在上面的例子上在進一步進行簡單的升級:
package com.example.chenzhu.myprojectblog;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MyHandleActivity extends AppCompatActivity { Handler handler = new Handler(){ //接受消息并且處理消息 @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what==1) { Toast.makeText(MyHandleActivity.this, "耗時操作開始" + msg.what, Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MyHandleActivity.this, "耗時操作結束可以更新UI" + msg.what, Toast.LENGTH_SHORT).show(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_handle); Button button = (Button)findViewById(R.id.sendHandle); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Message msg = new Message();//建立一個消息 msg.what=1; handler.sendMessage(msg);//發送一個消息 new MyTheard().start(); } }); } //模擬耗時操作 class MyTheard extends Thread{ @Override public void run() { super.run(); try { sleep(5); //模擬耗時操作結束 發送消息 Message msg = new Message(); msg.what=2; handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } }}
新聞熱點
疑難解答