
青岛android培训小编最新更新android资讯
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 }
实际运行这个例证安卓模仿3d touch模块,点击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要处理的内容会在主线程中处理安卓模仿3d touch模块,因此不希望占用很多的时间,从而引发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).
具体的例证不想写了。今天就到这儿吧。太累了。明天不在深入,而是扩展。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shouji/article-119696-1.html
恶意攻击诋毁用的吧
爱炸不炸