1、消息Handle
Activity中UI组件中的信息传递Handler,相信很多朋友都知道,Android为了线程安全,并不允许我们在UI线程外操作UI;很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUiThread()来更新,甚至更高级的事务总线。
一、handler的使用场景为么会有handler?(部分内容图片摘自http://www.runoob.com/w3cnote/android-tutorial-handler-message.html)
二、handler的消息处理机制
在Android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知。
- UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
- Handler:作用就是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象
- Message:Handler接收与处理的消息对象
- MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
- Looper:每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!
通俗一点讲:当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueue进行等待,由Looper按先入先出顺序取出,再根据message对象的what属性分发给对应的Handler进行处理!
2、服务端:
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import static com.xxx.zqLog.ZqLog.logger;
public class PileService extends Service {
// 6秒开始更新
private static final int UPDATE_TIMER = 1000 * 6;
private static final String TAG_MODULE_PILE = "xxx服务模块:";
private static final int RECEIVE_MESSAGE_CODE = 0x0001;
private static final int SEND_MESSAGE_CODE = 0x0002;
private Messenger clientMessenger = null;
private Messenger serviceMessenger = new Messenger(new ServiceHandler());
private class ServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
logger.debug(TAG_MODULE_PILE + "消息服务:消息队列");
if(msg.what == RECEIVE_MESSAGE_CODE){
Bundle data = msg.getData();
if(data != null){
String str = data.getString("msg");
logger.debug(TAG_MODULE_PILE + "消息服务:收到客户端如下信息: " + str);
}
clientMessenger = msg.replyTo;
if(clientMessenger != null){
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
logger.debug(TAG_MODULE_PILE + "接收消息时间:" + formatter.format(new Date(System.currentTimeMillis())));
//模拟耗时
try {
Thread.sleep(UPDATE_TIMER);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.debug(TAG_MODULE_PILE + UPDATE_TIMER + "秒后" + "服务向客户端回信");
logger.debug(TAG_MODULE_PILE + "发送消息时间:" + formatter.format(new Date(System
.currentTimeMillis())));
Message msgToClient = Message.obtain();
msgToClient.what = SEND_MESSAGE_CODE;
//可以通过Bundle发送跨进程的信息
Bundle bundle = new Bundle();
bundle.putString("xxxInformations", getJsonFromInfo());
msgToClient.setData(bundle);
try{
clientMessenger.send(msgToClient);
}catch (RemoteException e){
e.printStackTrace();
logger.debug(TAG_MODULE_PILE + "服务端向客户端发送信息失败: " + e.getMessage());
}
}
}
}
}
@Override
public void onCreate() {
logger.debug(TAG_MODULE_PILE + "消息服务创建");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
logger.debug(TAG_MODULE_PILE + "消息服务创建连接");
return serviceMessenger.getBinder();
}
@Override
public void onDestroy() {
logger.debug(TAG_MODULE_PILE + "消息服务创建销毁");
clientMessenger = null;
super.onDestroy();
}
private String getJsonFromxxxInfo() {
String json;
json = "{\"cc\":\"20\",\"mm\":\"ll\",\"id\":\"20173333\"," +
"\"ss\":\"message\"}";
return json;
}
}
AndroidManifest.xml文件:
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
<service
android:name="com.xxx.pileservice.PileService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.xxx.pileservice.PileService"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
</application>
3、客户端:
/**
* 消息处理
*/
private static final int SEND_MESSAGE_CODE = 0x0001;
private static final int RECEIVE_MESSAGE_CODE = 0x0002;
private boolean isBound = false;
private final String SERVICE_ACTION = "com.xxx.modulepileservice.PileService";
private Messenger serviceMessenger = null;
private Messenger clientMessenger = new Messenger(new ClientHandler());
//客户端用ClientHandler接收并处理来自于Service的消息
private class ClientHandler extends Handler {
@Override
public void handleMessage(Message msg) {
logger.debug(TAG_PROVIDER + "客户端消息队列:");
if (msg.what == RECEIVE_MESSAGE_CODE) {
Bundle data = msg.getData();
if (data != null) {
String str = data.getString("Informations");
logger.debug(TAG_PROVIDER + "客户端收到Service的消息: " + str);
}
}
}
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
logger.debug(TAG_PROVIDER + "客户端已连接!");
serviceMessenger = new Messenger(binder);
isBound = true;
Message msg = Message.obtain();
msg.what = SEND_MESSAGE_CODE;
Bundle data = new Bundle();
data.putString("msg", "你好,服务端,我是客户端");
msg.setData(data);
msg.replyTo = clientMessenger;
try {
logger.debug(TAG_PROVIDER + "客户端向service发送信息");
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
logger.debug(TAG_PROVIDER + "客户端向service发送消息失败: " + e.getMessage());
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
serviceMessenger = null;
isBound = false;
logger.debug(TAG_PROVIDER + "客户端断开连接");
}
};
private void bindMessageService(Context context) {
Intent intent = new Intent();
intent.setAction(SERVICE_ACTION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
PackageManager pm = context.getPackageManager();
ResolveInfo info = pm.resolveService(intent, 0);
if (info != null) {
String packageName = info.serviceInfo.packageName;
String serviceNmae = info.serviceInfo.name;
ComponentName componentName = new ComponentName(packageName, serviceNmae);
intent.setComponent(componentName);
try {
logger.debug(TAG_PROVIDER + "客户端调用bindService方法");
context.bindService(intent, conn, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
e.printStackTrace();
logger.debug(TAG_PROVIDER + e.getMessage());
}
}
}
推荐文章:一个帖子学会Android开发四大组件

本文详细介绍了Android中Handler和Messenger的使用场景与消息处理机制,包括Handler如何实现线程间的安全消息传递,以及Messenger如何应用于服务端与客户端之间的通信。
3310

被折叠的 条评论
为什么被折叠?



