Android多线程编程<二>Handler异步消息处理机制之Message
package zst.message01;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private Button button01; public static final int ONE = 1; //在主线程中创建的Handler对象,通常定义成static
public static Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ONE:
System.out.println("第一个Message-->" + "arg1=" + msg.arg1 + ",arg2=" + msg.arg2 + ",obj=" + msg.obj);
break;
default:
break;
}
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button01 = (Button) findViewById(R.id.button01);
button01.setOnClickListener(this);
} @Override
public void onClick(View v) {
if(v.getId() == R.id.button01){
//启动一个子线程
new Thread(new Runnable() { @Override
public void run() {
//获得Message对象的第一种方法:使用构造函数创建Message,这种方法不推荐使用
Message message = new Message();
message.arg1 = 100;
message.arg2 = 200;
message.what = ONE; //用于标识Message
message.obj = "Message_01";
//发送Message到主线程中
handler.sendMessage(message); } }).start(); } }
}

//获得Message对象的第二种方法
Message message = Message.obtain();
message.arg1 = 100;
message.arg2 = 200;
message.what = TWO; //用于标识Message
message.obj = "Message_02";
handler.sendMessage(message);
public static Message obtain()方法的源码如下:
// sometimes we store linked lists of these things
/*package*/ Message next;
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}
该方法将从全局消息槽中获得一个Message对象,从而避免再分配一块新的内存来创建Message对象。从上面可以看出,当全局消息槽中当前sPool不为null,则把sPool指向的Message对象赋给一个Message的临时引用,然后sPool再指向槽中的下一个Message,最后把临时引用m指向的Message对象返回给我们,这样全局消息槽中的Message可以得到重复使用,从而节省了一定的内存。如果sPool为null时,即消息槽为空,没有Message,这时才调用Message的构造函数来创建一个Message对象给我们。
//获得Message对象的第三种方法:
Message message = Message.obtain(handler);
message.arg1 = 100;
message.arg2 = 200;
message.what = THREE; //用于标识Message
message.obj = "Message_03";
//发送Message
message.sendToTarget();
public static Message obtain(Handler h)方法的源码如下:
/**
* Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
* @param h Handler to assign to the returned Message object's <em>target</em> member.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
从上面源码中可以看出:该方法内部还是通过public static Message obtain()方法从全局消息槽中返回一个Message对象给我们,然后把传入的Handler对象参数当成发送和接收该Message对象的目标Handler对象。由于该方法内部已经指定了处理Message对象的目标Handler对象,所以在发送Message消息时,不会再调用Handler对象的sendMessage(message)方法,而是直接使用Message对象的sendToTarget()方法发送。
//获得Message对象的第四种方法:
Message message = Message.obtain(handler, FOUR);
message.arg1 = 100;
message.arg2 = 200;
message.obj = "Message_04";
message.sendToTarget();
public static Message obtain(Handler h, int what)方法的源码如下:
/**
* Same as {@link #obtain()}, but sets the values for both <em>target</em> and
* <em>what</em> members on the Message.
* @param h Value to assign to the <em>target</em> member.
* @param what Value to assign to the <em>what</em> member.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what) {
Message m = obtain();
m.target = h;
m.what = what;
return m;
}
/**
* Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
* members.
* @param h The <em>target</em> value to set.
* @param what The <em>what</em> value to set.
* @param obj The <em>object</em> method to set.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.obj = obj;
return m;
}
public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj)方法源码:
/**
* Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
* <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members.
*
* @param h The <em>target</em> value to set.
* @param what The <em>what</em> value to set.
* @param arg1 The <em>arg1</em> value to set.
* @param arg2 The <em>arg2</em> value to set.
* @param obj The <em>obj</em> value to set.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what,
int arg1, int arg2, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
m.obj = obj;
return m;
}
public static Message obtain(Handler h, int what, int arg1, int arg2)方法源码:
/**
* Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
* <em>arg1</em>, and <em>arg2</em> members.
*
* @param h The <em>target</em> value to set.
* @param what The <em>what</em> value to set.
* @param arg1 The <em>arg1</em> value to set.
* @param arg2 The <em>arg2</em> value to set.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what, int arg1, int arg2) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
return m;
}
Message message = Message.obtain(handler, EIGHT, 100, 200);
message.obj = "Message_08";
Bundle b = new Bundle();
b.putString("name", "张三");
message.setData(b);
message.sendToTarget();
Android多线程编程<二>Handler异步消息处理机制之Message的更多相关文章
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类(转)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 最近创建了一个群,方便大家交流,群号: ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片载入类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...
- Android之Handler(异步消息处理)机制
1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步消息处理线程启动后会进入一个无限的循环体之中,每循 ...
- Android多线程编程<一>Android中启动子线程的方法
我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改 ...
- Android多线程----异步消息处理机制之Handler详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android异步消息处理机制(多线程)
当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如果不将这类操作放在子线程里去执行,就会导致主线程被阻塞住,从而影响用户对软件的正常使用. ...
- 【转】Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Andr ...
- Android 异步消息处理机制 让你在深入了解 Looper、Handler、Message之间的关系
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 非常多人面试肯定都被问到过,请问And ...
- Android线程与异步消息处理机制
在程序开发时,对于一些比较耗时的操作,我们通常会为其开辟一个单独的线程来执行,这样可以尽可能的减少用户等待的时间.在Android中,默认情况下,所有的操作都是在主线程中进行的,这个主线程负责管理与U ...
随机推荐
- Newtonsoft.Json反序列化(Deserialize)出错:Bad JSON escape sequence
使用Newtonsoft.Json反序列化收到的字串为JObject或其它支持的数据模型,有时错误,提示如下: Bad JSON escape sequence: \c. Path , positio ...
- MVC的SignalR例子
# SignalR学习 ASP.NET SignalR 是为.NET 开发者提供即时通讯Web 应用的类库.即时通讯Web服务就是服务器将内容自动推送到已经连接的客户端,而不是服务器等待客户端发起一个 ...
- java并发编程艺术
cas算法 概要 刚开始看这本书的时候很经常看到cas算法,个人觉得cas算法在并发编程中也是挺重要的的一部分,cas是比较并交换的意思(compare and swap),campareAndSwa ...
- setsockopt设置socket状态
setsockopt设置socket状态 1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsoc ...
- JPanel JScrollPanel
JPanel 和 JScrollPanel 都属于面板,也是 Swing 中间容器,可以作为容器存放组件,但必须被添加到其他容器中. JPanel 可以聚集一些组件来布局, JScrollPanel ...
- ABP Xunit单元测试 第五篇
1.创建如下的项目结构 public class TestName { public bool ValidateName(string Name) { if (Name == "yin&qu ...
- S 实现精确加减乘除
//加法函数 function accAdd(arg1, arg2) { var r1, r2, m; try { r1 = arg1.toString().split(".")[ ...
- ssh 配置免密失败
多数情况下,可以登录成功.但是也会出现配置不正确,导致失败的时候. 1.检查authorized_keys文件权限,并设置为700 chmod 700 authorized_keys 2.检查/etc ...
- ABP框架系列之九:(Abp-Session-会话)
Introduction ASP.NET Boilerplate provides IAbpSession interface to obtain current user and tenant wi ...
- s2 Docker环境的快速搭建方法
常规linux下安装 centos7 下配置docker源并安装 cat >/etc/yum.repos.d/docker.repo< [dockerrepo] name=Docker R ...