Client: package com.pignet.messengerdemo2; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static TextView tvMsgFromService; Button btnSend; EditText etClient; private Messenger mService; private Messenger mGetReplyFromService =new Messenger(new MessengerHandler()); private static class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what){ case 1: tvMsgFromService.setText(msg.getData().getString("reply")); break; } super.handleMessage(msg); } } private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService=new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnSend= (Button) findViewById(R.id.btn_send); etClient= (EditText) findViewById(R.id.et_client); tvMsgFromService = (TextView) findViewById(R.id.tv_msg_from_service); Intent intent= new Intent(MainActivity.this,MessengerService.class); bindService(intent,mConnection, Context.BIND_AUTO_CREATE); btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String msgFromClient; Message msg = Message.obtain(null,0); Bundle data = new Bundle(); if((msgFromClient=String.valueOf(etClient.getText()))==null){ Toast.makeText(MainActivity.this,"The Message is null",Toast.LENGTH_SHORT).show(); }else{ data.putString("msg", msgFromClient); msg.setData(data); msg.replyTo= mGetReplyFromService; try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } } }); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); } }
package com.pignet.messengerdemo2; 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 android.support.annotation.Nullable; import android.util.Log; /** * Created by DB on 2017/7/2. */ public class MessengerService extends Service { private static final String TAG="MessengerService"; private static class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what){ case 0: Log.i(TAG, "receive msg from client: "+msg.getData().getString("msg")); Messenger mService = msg.replyTo; Message replyMessage = Message.obtain(null,1); Bundle bundle = new Bundle(); bundle.putString("reply","您的信息"+msg.getData().getString("msg")+"已收到,稍后会有回复"); replyMessage.setData(bundle); try{ mService.send(replyMessage); } catch (RemoteException e) { e.printStackTrace(); } } super.handleMessage(msg); } } private final Messenger mMessenger = new Messenger(new MessengerHandler()); @Nullable @Override public IBinder onBind(Intent intent) { return mMessenger.getBinder(); } }
<service android:name=".MessengerService" android:process=":romote"> </service>
运行结果以下java
public Messenger(Handler target) { mTarget = target.getIMessenger(); }
public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }
由于以前提到过Messenger的底层实现是AIDL,因此这边我看这个IMessage和那个IBookManager有的相似,点开后发现确实如此android
public interface IMessenger extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.os.IMessenger { private static final java.lang.String DESCRIPTOR = "android.os.IMessenger"; public Stub() { this.attachInterface(this, DESCRIPTOR); } public static android.os.IMessenger asInterface(...} public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {...} private static class Proxy implements android.os.IMessenger {...} public void send(android.os.Message msg) throws android.os.RemoteException; }
以前咱们为BookManager类定义的方法是一个addBook和getBookList,而这边咱们发现Messenger对AIDL的封装中加入的是一个send方法。服务器
那这个方法是在哪里实现的呢。app
private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.this.sendMessage(msg); } }
它是在Handler类中的MessengerImpl方法中获得实现的,这也就能够解释咱们发送的message能够在Handler的handleMessage中出现了。ide
最后咱们再回到Messenger类中看看Messenger的另外一个重要方法:函数
public void send(Message message) throws RemoteException { mTarget.send(message); }
这里咱们就能够串联起来了,Messenger类经过传入Handler或是IBinder来得到IMessenger的实例,而后调用send方法实际是在远程调用IMessenger的send方法。this
这里咱们就差很少把Messenger的机制理清了。spa
最后附上刚才实现的例子的一个简图:code