今天通过以前写的简单的代码,分享通过Messenger 完成跨进成通信的使用,大神等请绕行。
接的外包越来越复杂,使我不得不急需从以前凌乱的成型的、未成型的项目中整理出一些主要的框架 – 2013. 中旬。
也是由于一般来说Messenger相比AIDL是把所有的请求都放到一个请求队列,逐一处理,无法支持同时处理并且Messenger仅仅只是通过传递message进行通讯,所以所有的操作只能在对方的Handle中处理,对于架构来说也不是很好,所以最近再次整理的时候需要将这些替换为AIDL通信,但是Messenger通信比较简单,还是很值得mark的,因此,先上当初写的拙码:
———— 服务端: SocketServer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| package cn.dreamtobe.service; 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 cn.dreamtobe.net.SocketHandle; import cn.dreamtobe.net.SocketHandle.SocketHandleCallBack; import cn.dreamtobe.order.CmdOrder; import cn.dreamtobe.utils.LogUtils; import cn.dreamtobe.utils.Util;
public class SocketService extends Service implements Runnable { private ServiceHandle mHandle = new ServiceHandle(); private SocketHandle mSocketHandle = null; private volatile boolean mbStop = false; private final String mHostIp = Util.getSocketHostIP(); private final int mPort = Util.getSocketPort(); private Messenger mcMessenger = null; private Messenger msMessenger = new Messenger(mHandle); private LogUtils mLogUtils = LogUtils.getInstance(); private class ServiceHandle extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case CmdOrder.CMD_SERVICE_STOP: mbStop = true; stopSelf(); break; case CmdOrder.CMD_MESSAGE_SEND: mcMessenger = msg.replyTo; Bundle bundle = msg.getData(); String sendMsg = bundle.getString("client"); sendString(sendMsg); default: break; } } } private Message mSendMsg = null; private void replyClient(int cmd, String replyMsg) { if (mSendMsg == null) { mSendMsg = new Message(); } mSendMsg.what = cmd; Bundle bundle = new Bundle(); bundle.putString("socketservice", replyMsg); mSendMsg.setData(bundle); try { mcMessenger.send(mSendMsg); } catch (Exception e) { } } private void sendString(String sendMsg) { mLogUtils.NetSendLog("socket服务请求发送: " + sendMsg); mSocketHandle.SendString(sendMsg); } @Override public IBinder onBind(Intent intent) { mLogUtils.SysLog("Socket Service onBind"); return msMessenger.getBinder(); } @Override public void onCreate() { super.onCreate(); mSocketHandle = new SocketHandle(mHostIp, mPort, mCallBack); mSocketHandle.start(); mLogUtils.SysLog("Socket Service onCreate"); } @Override public void onDestroy() { super.onDestroy(); mSocketHandle.stop(); mLogUtils.SysLog("Socket Service onDestroy"); } @Override public void run() { if (!mbStop) { } } private SocketHandleCallBack mCallBack = new SocketHandleCallBack() { @Override public void SucceedSendString() { } @Override public void SucceedReconnect() { } @Override public void ReConnectFailOnSendString() { } @Override public void FailReconnect() { } @Override public void ErrorOnSendString() { } @Override public void BeginReConnect() { } @Override public void BackMessage(String msg) { if (mcMessenger == null) { return; } replyClient(CmdOrder.CMD_MESSAGE_RECEIVE, msg); } }; }
|
——————– BaseActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| package cn.dreamtobe.activity; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; 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 cn.dreamtobe.order.CmdOrder; import cn.dreamtobe.tool.GlobalTool; import cn.dreamtobe.utils.LogUtils; import cn.dreamtobe.utils.VariUtils;
public abstract class BaseActivity extends Activity { private static MyHandler mHandler = null; private static int mnBaseAct = 0;
protected Messenger mcMessenger = null;
protected Messenger msMessenger = null; private static BaseActivity mCurBaseActivity = null; private LogUtils mLogUtils = LogUtils.getInstance(); private boolean mIsBind = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mnBaseAct++; preConfigure(); if (mHandler == null) { mHandler = new MyHandler(); } VariUtils.gCurActivity = this; mCurBaseActivity = this; configure(); initUtils(); initControl(); initUI(); } protected void preConfigure() { } public void BindService() { if (!mIsBind) { mLogUtils .SysLog(this.getClass().toString() + " Bind SocketService"); mIsBind = bindService(new Intent(VariUtils.SocketServiceAction), mSerConn, BIND_AUTO_CREATE); } } public void unBindService() { if (mIsBind) { mLogUtils.SysLog(this.getClass().toString() + " unBind SocketService"); unbindService(mSerConn); mIsBind = false; } } @Override protected void onResume() { super.onResume(); VariUtils.gCurActivity = this; mCurBaseActivity = this; } @Override protected void onDestroy() { super.onDestroy(); unBindService(); if (--mnBaseAct == 0) { } } protected abstract void configure(); protected abstract void initUtils(); protected abstract void initControl(); protected abstract void initUI(); public void sendMessage(int flag) { mHandler.sendEmptyMessage(flag); } public void sendMessageDely(int flag, long delayMillis) { mHandler.sendEmptyMessageDelayed(flag, delayMillis); } public void sendMessage(Message msg) { mHandler.sendMessage(msg); } protected void ToastShow(String message) { mHandler.toast_message = message; mHandler.sendEmptyMessage(MyHandler.SHOW_STR_TOAST); } private static class MyHandler extends Handler { public static final int SHOW_STR_TOAST = 0; private String toast_message = null; @Override public void handleMessage(Message msg) { if (!Thread.currentThread().isInterrupted()) { switch (msg.what) { case SHOW_STR_TOAST: GlobalTool.showCustomToast(mCurBaseActivity, toast_message, 1); break; default: mCurBaseActivity.handleOtherMessage(msg); break; } } } }
protected abstract void handleOtherMessage(Message msg); private ServiceConnection mSerConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mLogUtils.SysLog("ServiceUnConnected"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { mLogUtils.SysLog("ServiceConnected"); msMessenger = new Messenger(service); mcMessenger = new Messenger(mHandler); } }; protected Message mSendMsg = null; public void sendSocketServiceMsg(int cmd, String msg) { if (msMessenger == null) { return; } if (mSendMsg == null) { mSendMsg = new Message(); mSendMsg.replyTo = mcMessenger ; } mSendMsg.what = cmd; Bundle mBundle = new Bundle(); mBundle.putString("client", msg); mSendMsg.setData(mBundle); try { msMessenger.send(mSendMsg); if (cmd == CmdOrder.CMD_SERVICE_STOP) { msMessenger = null; } } catch (RemoteException e) { mLogUtils .SysLogE("error on Send to SocketService: " + e.toString()); e.printStackTrace(); } } }
|
虽然我也想忽略一切直接分析Messenger,但是,这里还是提下,其中所有Socket有关的机制都封装在SocketHandle当中,其中一些主要的反馈通过接口SocketHandleCallBack在SocketService中实现。
那么,透过代码,我们可以看到在SocketService与BaseActivity中都有:
1 2 3 4 5 6 7 8
|
protected Messenger mcMessenger= null;
protected Messenger msMessenger = null;
|
对于SocketService(下称为Service端)而言mcMessenger来自BaseActivity(下称为Client端):mcMessenger = msg.replyTo; 而msMessenger 为Service端通过传入对应处理的Handle创建,所有的客服端发过来的有关处理都在这个Handle中处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private class ServiceHandle extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case CmdOrder.CMD_SERVICE_STOP: mbStop = true; stopSelf(); break; case CmdOrder.CMD_MESSAGE_SEND: mcMessenger = msg.replyTo; Bundle bundle = msg.getData(); String sendMsg = bundle.getString("client"); sendString(sendMsg); default: break; } } }
|
并且在onBind时,返回Service端Messenger的IBinder:
1 2 3 4 5
| @Override public IBinder onBind(Intent intent) { mLogUtils.SysLog("Socket Service onBind"); return msMessenger.getBinder(); }
|
对于Client端而言,mcMessenger的创建类似与msMessenger ,也是通过传入对应处理的Handle创建,而msMessenger是通过连接成功以后传入参数IBinder进行创建,还有一点值得注意的是,在发送message给Service端时,将message的replyTo赋值为mcMessenger,别忘了我们在Service端时是如何取得Client端的Messenger进行通信的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
protected abstract void handleOtherMessage(Message msg); private ServiceConnection mSerConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mLogUtils.SysLog("ServiceUnConnected"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { mLogUtils.SysLog("ServiceConnected"); msMessenger = new Messenger(service); mcMessenger = new Messenger(mHandler); } }; protected Message mSendMsg = null; public void sendSocketServiceMsg(int cmd, String msg) { if (msMessenger == null) { return; } if (mSendMsg == null) { mSendMsg = new Message(); mSendMsg.replyTo = mcMessenger; } mSendMsg.what = cmd; Bundle mBundle = new Bundle(); mBundle.putString("client", msg); mSendMsg.setData(mBundle); try { msMessenger.send(mSendMsg); if (cmd == CmdOrder.CMD_SERVICE_STOP) { msMessenger = null; } } catch (RemoteException e) { mLogUtils .SysLogE("error on Send to SocketService: " + e.toString()); e.printStackTrace(); } }
|
至此,已经简单的通过Messenger完成进程间通信。