如果想要进行IPC通信,一般写一个AIDL接口,再写一个Service子类,然后实现AIDL接口 当做IBinder返回给Activity界面层。
如果不想写AIDL接口文件,只是单I线程中与Service进行通信 我们可以用Android写好的Messenger类来处理,一样能将消息传递给Service进行通信。
先写上基本代码:
public class MyService extends Service { Messenger messenger = null; public MyService() { } @Override public void onCreate() { super.onCreate(); messenger = new Messenger(handler);//实例化一个对象,并将Handler传入绑定,UI MQ消息检测 } Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Log.d("","Msg:" + msg.what + ";" + msg.obj); } }; /* (non-Javadoc) * @see android.app.Service#onBind(android.content.Intent) */ @Override public IBinder onBind(Intent arg0) { return messenger.getBinder();//返回Binder接口 } }
MyActivity 中部分代码
<span style="white-space:pre"> </span>Messenger messenger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService(new Intent(this,MyService.class), conn, Context.BIND_AUTO_CREATE);//一样绑定一个Connection } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName cn) { } @Override public void onServiceConnected(ComponentName cn, IBinder ibiner) { messenger = new Messenger(ibiner);//得到Service中的Messenger Log.d("","OK messenger connected........"); } }; public void sendMsg(int what, String msg){ //这个方法就是自己的业务信息发送消息 传递到Service中 有 Handler处理。 if (messenger == null) { return; } Message msg1 = Message.obtain(); msg1.what = what; msg1.obj = msg; try { messenger.send(msg1); } catch (RemoteException e) { e.printStackTrace(); } }
以上的代码非常简单。
下面看看Messenger源码其实是个包装类,它本身就是可以被IPC投递的对象,因为用了Parcelable接口。
public Messenger(Handler target) { //之前传递的Handler到这里, mTarget = target.getIMessenger(); //得到的其实是Handler里面的IMessenger接口 } public void send(Message message) throws RemoteException { mTarget.send(message);//具体有IMessenger接口发送 } public IBinder getBinder() { return mTarget.asBinder(); } //注释我都去掉了
再看看Handler源码是如何发消息的
final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl();//这个实现了IMessenger远程IPC接口,AIDL return mMessenger; } } private final class MessengerImpl extends IMessenger.Stub { //实现在这个地方 public void send(Message msg) { Handler.this.sendMessage(msg);//本质上还是有 Handler来发送消息 } }
可以看出IMessenger这个远程通信IPC接口 包含了send(Message msg)方法,其本质还是获取了我们MyService中的Handler对象进行发送消息。
IMessenger.aidl
内容如下
package android.os; import android.os.Message; /** @hide */ oneway interface IMessenger { void send(in Message msg); }
以上源码是4.1版本的 新版的源码没去研究,这部分应该是一致的。下面是个简单的草图,算是个总结。
时间: 2024-10-20 09:53:57