Android笔记(三十四) Android中线程之间的通信(六)Handle中的post()方法详解
我们之前都是使用sendMessage()方法来发送消息,使用handleMessage来处理消息的,今天我们来看另外一种方法,先看代码:
package cn.lixyz.handlertest; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity { private Button button;
private Handler handler = new Handler();
private TextView textView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TestThread t = new TestThread();
t.start();
}
}); } class TestThread extends Thread {
@Override
public void run() {
super.run();
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Log.d("TTTT", (i + 1) + " 秒");
try {
Thread.sleep(1000 * 1);
textView.setText("5秒后修改的内容");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}; handler.post(r);
}
} }
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="更改前"
android:textSize="30sp" /> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="Send Message" /> </LinearLayout>
acitivit_main.xml
点击按钮,运行结果:
从代码中我们可以看到,我新建了一个线程,线程中创建了一个Runnable对象,这个Runnable对象中有修改UI的操作,然后使用调用了Handler的 post() 方法,那么我们就来看一下这个 post() 究竟是如何实现的。
查看Handler的源代码,找到post()方法
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
我们发现,其实post方法直接调用了一个延时发送消息的方法 sendMessageDelayed() ,只不过延时为0,继续找到 getPostMessage() 方法
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
在上面的代码中,我们发现,getPostMessage方法内新获取了一个Message对象,并且将我们传入的Runnage对象赋值给了这个Message对对象的 callback 属性,然后将之返回
所以说, post() 方法的本质就是将一个Runnable对象赋值给一个Message属性的 callback 属性,然后将这个Message对象放入到消息队列当中去
而之前我们说过,Looper的 loop() 方法会循环的从消息队列中取出消息,那么这时候Looper是怎么工作的呢,找到Looper的 loop() 方法
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity(); for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
} // This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
} msg.target.dispatchMessage(msg); if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
} // Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
} msg.recycle();
}
}
和之前说的一样,loop()方法执行之后,同样的先拿到Looper对象,之后开始循环从消息队列中取出消息,执行到 msg.target.dispatchMessage(msg); 因为Message的 target 属性是 Handler 类型的,我们去看Handler的 despatchMessage 方法
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
可见,先进对收取到的Message对象的 callback 属性进行判断,如果不为空,为调用 handleCallback 方法,查看 handleCallback 方法
private static void handleCallback(Message message) {
message.callback.run();
}
message.callback.run(); 直接调用了Runnable对象的 run() 方法,而不是创建一个新线程,然后再调用这个线程的start方法。
最新文章
- 多线程之异步编程: 经典和最新的异步编程模型,async与await
- Async and Await 异步和等待
- Java学习一
- jsp分页代码之pageUtil类
- JQuery replace 替换全部
- mybatis 主键UUID生成策略
- Echarts环形进度使用 【1 简单的使用示例】
- Apache Spark 2.2.0 中文文档 - Submitting Applications | ApacheCN
- python中的slice用法
- CSS3之border-radius圆角
- Python-Jupyter Notebook使用技巧
- 关于AMD 、CMD、 commonjs的认识
- <;笔记>;原生PHP访问TP模板变量
- Spring Boot 构建电商基础秒杀项目 (三) 通用的返回对象 &; 异常处理
- 微信小程序地图报错——ret is not defined
- stm32启动文件ld md hd cl vl xl分析及选择
- shell编程:基本语法
- C++中的npos,size_t,size_type
- codeforces水题100道 第六题 Yandex.Algorithm 2011 Qualification 2 A. Double Cola (math)
- sencha touch 在线实战培训 第一期 第六节
热门文章
- 123457123456#1#----com.MC.EnglishGame98--前拼后广--jp英语-mc
- 【docker 镜像源】解决quay.io和gcr.io国内无法访问的问题
- DB2中ALTER TABLE的使用
- 【Leetcode_easy】944. Delete Columns to Make Sorted
- nnexus3 破解密码
- Office 2010 经验总结
- 如何提高程序员的键盘使用效率(搬砖工人的自我修养(tucao))
- php类的继承(基本概念,访问权限修饰符,重写override)
- 在ensp上简单的配置交换机
- Mysql 排序优化