Android消息处理Handler与Message
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()); } } }
推荐文章: