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