Handler機制及基本使用也已經是老生常談了~~~
1、概述
Android中拒絕子線程中更新UI。且主線程中過多執行耗時操作會造成界面卡頓導致ANR影響用戶體驗,因此Handler線程間通信的信使應運而生。Handler有兩個主要用途:(1)調度消息和runnable對象作為將來的執行;及(2)將被執行在一個不同的線程自己的方法。
1.Handler基本原理
主線程(UI線程)
子線程(work線程)
Message 消息類
MessageQueue消息隊列(數據結構中的隊列,先進先出規則)
Handler對象發送消息對象到消息隊列中,Looper循環取出消息隊列中的消息對象,并將該消息對象設置為發送該消息對象的handler的handleMessage方法的參數,若消息隊列中沒有消息則處于阻塞狀態。
2、Handler的基本使用
1.UI線程中發送消息并在UI線程中執行
Handler發送和處理消息的幾個方法:
void handleMessage(Message msg):處理消息的方法,該方法通常被重寫。 final boolean hasMessage(int what):檢查消息隊列中是否包含有what屬性為指定值的消息 final boolean hasMessage(int what ,Object object):檢查消息隊列中是否包含有what好object屬性指定值的消息 sendEmptyMessage(int what):發送空消息 final Boolean send EmptyMessageDelayed(int what ,long delayMillis):指定多少毫秒發送空消息 final boolean sendMessage(Message msg):立即發送消息 final boolean sendMessageDelayed(Message msg,long delayMillis):多少秒之后發送消息
由于代碼比較簡單,直接上代碼了~
/** * Created by magic on 2016年10月23日.主線程中發送消息主線程中接收 */ @SuppressLint(quot;HandlerLeakquot;) public class MainActivity extends Activity { TextView textView; Button button; Handler handler = new Handler() { // 接收消息并處理 public void handleMessage(Message msg) { System.out.println(Thread.currentThread().getName()); // main System.out.println(quot;消息-gt;quot; msg.arg1 quot;-quot; msg.obj); // 消息-gt;1-obj消息 }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) findViewById(R.id.btn); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // 主線程中發送消息 Message message = handler.obtainMessage(); message.arg1 = 1; message.obj = quot;obj消息quot;; handler.sendMessage(message); // 輸出當前線程名稱 System.out.println(Thread.currentThread().getName()); // main } }); } }
2.Work線程中發送消息并在UI線程中執行
/** * Created by magic on 2016年10月23日.Work線程中發送消息 UI線程中接收消息 */ @SuppressLint(quot;HandlerLeakquot;) public class TwoActivity extends Activity { Button button; Handler handler = new Handler() { // 接收消息并處理 public void handleMessage(Message msg) { System.out.println(Thread.currentThread().getName()); // main System.out.println(quot;消息-gt;quot; msg.arg1 quot;-quot; msg.obj); // 消息-gt;1-obj消息 }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button) findViewById(R.id.btn); button.setText(quot;Work-gt;UIquot;); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Thread thread = new Thread(new Runnable() { @Override public void run() { // work線程中發送消息 Message message = handler.obtainMessage(); message.arg1 = 1; message.obj = quot; obj消息quot;; System.out.println(Thread.currentThread().getName()); // Thread-400 handler.sendMessage(message); // 輸出當前線程名稱 } }); // 開啟線程 thread.start(); } }); } }
3.UI線程中發送消息并在Work線程執行
基本步驟:
1.準備Looper對象
2.生成handler對象
3.Looper.loop()循環取出Message對象
/** * Created by magic on 2016年10月23日.UI線程中發送消息 work線程中接收消息 */ @SuppressLint(quot;HandlerLeakquot;) public class ThreeActivity extends Activity { Button button; Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.tev); button = (Button) findViewById(R.id.btn); button.setText(quot;UI-gt;Workquot;); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Message message = handler.obtainMessage(); message.arg1 = 1; message.obj = quot; obj消息quot;; // 主線程中發送消息 handler.sendMessage(message); System.out.println(Thread.currentThread().getName()); // main } }); new MyThread().start(); } class MyThread extends Thread { @Override public void run() { // 準備Looper對象 Looper.prepare(); handler = new Handler() { public void handleMessage(Message msg) { System.out.println(Thread.currentThread().getName()); // Thread-401 System.out.println(quot;消息-gt;quot; msg.what quot;-quot; msg.obj); // 消息-gt;0- obj消息 }; }; // 循環取出消息隊列中的消息對象 Looper.loop(); super.run(); } } }
3、Handler post方法的使用
new Handler().post(Runnable r) new Handler().postAtFrontOfQueue(Runnable r); new Handler().postAtTime(Runnable r, uptimeMillis); new Handler().postAtTime(Runnable r, token, uptimeMillis); new Handler().postDelayed(Runnable r, delayMillis);
Handler執行post方法會將參數Runnable對象,設置成Message的callback屬性Message消息對象加入隊列,如下:
Handler-gt;post-gt;Message.callback=r-gt;join MessageQueue
該Runnable對象的run方法會在UI線程中執行,當取出Message對象時判斷出該Message的callback不為null,于是調用handleCallback(msg)方法,該方法內部執行callback.run()方法。因為未開啟新的線程,所以run方法內部不能執行耗時操作。
如有問題懇請指正,謝謝!
END.
Tags: 線程 安卓開發
文章來源:http://blog.csdn.net/magic_jss/article/details/529