編輯:關於android開發
在上篇 Handler 原理分析和使用(一)中,介紹了一個使用Handler的一個簡單而又常見的例子,這裡還有一個例子,當然和上一篇的例子截然不同,也是比較常見的,實例如下。
1 import android.os.Handler;
2 import android.os.Looper;
3 import android.os.Message;
4 import android.os.MessageQueue;
5 import android.support.v7.app.AppCompatActivity;
6 import android.os.Bundle;
7 import android.view.View;
8 import android.widget.Button;
9 import android.widget.TextView;
10
11 public class MainActivity extends AppCompatActivity implements View.OnClickListener{
12
13 private TextView myTextView;
14 private Button myButton;
15 private Handler myHandler;
16 @Override
17 protected void onCreate(Bundle savedInstanceState) {
18 super.onCreate(savedInstanceState);
19 setContentView(R.layout.activity_main);
20 myHandler = new Handler();
21 myTextView = (TextView)this.findViewById(R.id.text_view);
22 myButton = (Button)this.findViewById(R.id.post);
23 myButton.setOnClickListener(this);
24 }
25
26 @Override
27 public void onClick(View view) {
28 int id = view.getId();
29 if(id == R.id.post){
30 Runnable updateUI = new Runnable() {
31 @Override
32 public void run() {
33 myTextView.setText("I get Post Message");
34 }
35 };
36 //將該線程發送到主線程運行
37 myHandler.post(updateUI);
38 }
39 }
40 }
實際運行這個例子,點擊Button之後,TextView文字內容會變成“I get Post Message”。為什麼會是這樣,我們從源碼開始著手查看。
先看Handler的post(Runnable)方法(post還有幾個姊妹方法,這裡不再一一論述,都是殊途同歸)。源碼如下:
1 public final boolean post(Runnable r)
2 {
3 return sendMessageDelayed(getPostMessage(r), 0);
4 }
調用了sendMessageDelayed(...), 先看getPostMessage(r),源碼如下:
1 private static Message getPostMessage(Runnable r) {
2 //獲取消息池中的一個消息
3 Message m = Message.obtain();
4 //將Runnable作為消息的callback
5 m.callback = r;
6 return m;
7 }
在看sendMessageDelayed(Message,int)的源碼:(在Handler 原理分析和使用(一)中有說明)
1 public final boolean sendMessageDelayed(Message msg, long delayMillis)
2 {
3 if (delayMillis < 0) {
4 delayMillis = 0;
5 }
6 return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
7 }
8 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
9 MessageQueue queue = mQueue;
10 if (queue == null) {
11 RuntimeException e = new RuntimeException(
12 this + " sendMessageAtTime() called with no mQueue");
13 Log.w("Looper", e.getMessage(), e);
14 return false;
15 }
16 return enqueueMessage(queue, msg, uptimeMillis);
17 }
18 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
19 //綁定Handler
20 msg.target = this;
21 if (mAsynchronous) {
22 msg.setAsynchronous(true);
23 }
24 //將Message推入MessageQueue
25 return queue.enqueueMessage(msg, uptimeMillis);
26 }
實際上和sendMessage(Message)一樣的流程。當然了緊接著Looper.loop()。然後調用到dispatchMessage(Message) 該方法需要在此重新說明。看源碼:
1 public void dispatchMessage(Message msg) {
2 if (msg.callback != null) {
3 //如果message的callback不為空,則
4 handleCallback(msg);
5 } else {
6
7 if (mCallback != null) {
8 //如果Handler的callback不為空,則
9 if (mCallback.handleMessage(msg)) {
10 return;
11 }
12 }
13 //處理Message
14 handleMessage(msg);
15 }
16 }
在進入handleCallback(Message)方法查看源碼:
1 private static void handleCallback(Message message) {
2 //直接執行run方法
3 message.callback.run();
4 }
注意,此時message已經是主線程對象。因此調用run方法就是在主線程中運行。
此外還需要注意,runnable要處理的內容會在主線程中處理,因此不能夠占用太多的時間,從而造成ANR。
--------------------------------------------------------------------------------------------
之所以用一條線隔開,是因為還有一個實例需要說明。請注意dispatchMessage(message)裡面的這段代碼:
if (mCallback != null) {
//如果Handler的callback不為空,則
if (mCallback.handleMessage(msg)) {
return;
}
}
這個mCallback是從哪裡來,這個有引出Handler的另一個使用方法。
首先來看Handler的初始化方法,有一下幾個:
1. publicHandler()
2. publicHandler(Callback)
3. publicHandler(Looper)
4. publicHandler(Looper, Callback)
第1,3個一眼看去就明白。第4個只要明白第2個也就通了。
關鍵點,Callback是什麼?是一個接口。源碼如下:
1 public interface Callback {
2 public boolean handleMessage(Message msg);
3 }
該接口實際上是要求實現handleMessage(Message)方法,相信這個方法大家都不陌生。
再看該初始化方法:
1 Handler handler = new Handler(new Handler.Callback() {
2 @Override
3 public boolean handleMessage(Message msg) {
4 return false;
5 }
6 });
這裡已經很明顯了。就是重新定義了handleMessage方法。那麼在dispatchMessage方法中如果發現mCallback不為空,則所有的消息都執行該Callback定義的handleMessage(Message).
具體的例子不想寫了。今天就到這裡吧。太累了。明天不在深入,而是擴展。
Android5.0新特性-Material Design
Android5.0新特性-Material Design 概述 2014年,Google攜Android5.X重裝歸來,全新的UI設計和更加優化的性能,令開發者眼前一亮
Android通過achartengine畫折線圖,achartengine折線圖
Android通過achartengine畫折線圖,achartengine折線圖因為前段時間Android項目中用到了折線圖的功能,在查資料的過程中發現acharten
lesson3-Qt對話框
lesson3-Qt對話框一、QDialog類1、對話框的概念對話框在各種軟件中都會使用到,一般用來給用戶提示信息或者接收用戶反饋的信息,因此對話框是應用程序和用戶交互的
android中菜單(menu)的基本知識,androidmenu
android中菜單(menu)的基本知識,androidmenu(一)選項菜單 1、簡單的創建菜單: 1 @Override 2 public boole