Messenger在跨程序通信中的使用
事先說明:
本人也是個初學者,是以本文是從初學者的角度入手,如果有不妥的地方請留言教導我,謝謝。
本篇文章主要針對講解Messenger的使用和Messenger在應用層上的原了解析和Messenger在服務端的回複。
什麼是Messenger?
Messenger可以翻譯為信使,Messenger是一種輕量級的IPC方案,通過它可以在不同程序中傳遞Message對象,在Message中放入我們需要傳遞的資料,就可以實作資料的程序間傳遞了。
步驟一:Messenger的使用
服務端的編寫:
public class MessagerService extends Service {
//辨別
public static final int GET_RESULT = 1;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private final Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("服務端的消息:" , msg.getData().getString("data"));
break;
default:
super.handleMessage(msg);
break;
}
}
});
}
在manifests中配置service:
<service
android:name=".Messager.MessagerService"
android:exported="true" />
用戶端的編寫(在另一個應用中):
public class MessengerActivity extends AppCompatActivity {
//辨別
public static final int GET_RESULT = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//綁定服務
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
bindService(intent, conn, BIND_AUTO_CREATE);
}
/**
* 服務回調方法
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//獲得消息者
Messenger messenger = new Messenger(service);
//建立空消息
Message message = Message.obtain(null, GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("data", "這是用戶端發過去的消息");
//往消息中存資料
message.setData(bundle);
//消息者發送消息
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//解綁服務,回收資源
unbindService(conn);
}
}
啟動服務端的Activity,并開啟服務:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
startService(new Intent(this, MessagerService.class));
}
}
接着啟動用戶端,檢視測試結果:
08-21 06:18:25.521 4154-4154/com.handsome.boke I/服務端的消息:: 這是用戶端發過去的消息
步驟二:Messenger在應用層上的原了解析
我們追随到Messenger的建立方法中,檢視源碼可以知道,底層是使用AIDL:
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
關于AIDL的使用和原理分析,這裡參照我的CSDN部落格,裡面有詳細的分析,Android基礎——初學者必知的AIDL在應用層上的Binder機制,http://blog.csdn.net/qq_30379689/article/details/52253413
步驟三:Messenger可以接受到用戶端的消息後進行回複,這裡就類似于郵箱自動回複的功能
改一下服務端的代碼:
public class MessagerService extends Service {
//辨別
public static final int GET_RESULT = 1;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private final Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("服務端的消息:" , msg.getData().getString("data"));
//------------------------修改的代碼----------------------
//接受到消息後,進行回複
//通過replyTo拿到Messenger對象
Messenger messenger = msg.replyTo;
Message message = Message.obtain(null,GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("reply","好的,我收到你的資訊了");
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
});
}
改一下用戶端的代碼:
public class MessengerActivity extends AppCompatActivity {
//辨別
public static final int GET_RESULT = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//綁定服務
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
bindService(intent, conn, BIND_AUTO_CREATE);
}
/**
* 服務回調方法
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//獲得消息者
Messenger messenger = new Messenger(service);
//建立空消息
Message message = Message.obtain(null, GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("data", "這是用戶端發過去的消息");
//---------------------------修改的代碼--------------------------
message.replyTo = replyMessenger;
//往消息中存資料
message.setData(bundle);
//消息者發送消息
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//解綁服務,回收資源
unbindService(conn);
}
//---------------------------修改的代碼--------------------------
private Messenger replyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("用戶端的消息:", msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
檢視我們的測試結果:
08-21 07:34:51.032 12808-12808/com.handsome.boke I/服務端的消息:: 這是用戶端發過去的消息
08-21 07:34:51.224 12784-12784/com.handsome.app2 I/用戶端的消息:: 好的,我收到你的資訊了