使用Messenger進行跨應用(程序)通訊
阿新 • • 發佈:2018-12-18
使用Messenger進行跨程序通訊
Messenger可以翻譯為信使,使用它我們可以進行跨程序通訊.Messengers是一種輕量的IPC,通過構造方法可以輕鬆的看出它的底層是現實AIDL.
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
Messenger的使用方法很簡單
服務端
需要在服務端建立一個Service,來處理客戶端的連線請求,同時建立一個Handler來處理接受到的訊息,然後在通過Handler建立一個Messenger物件,最後在Service的onBind()
package com.lixxy.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 android.os.RemoteException;
import android. support.annotation.Nullable;
import android.util.Log;
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind( Intent intent) {
Log.e(TAG, "連線了");
return mMessenger.getBinder();
}
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
//獲取client傳送的訊息
Log.e(TAG, msg.getData().getString("client"));
//收到訊息後給client傳送訊息
Messenger client = msg.replyTo;
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("service", "Hello,Client");
message.setData(bundle);
message.what = 200;
try {
client.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
}
服務端的service配置
在AndroidManifest中加入
<!--permission可加可不加,如果加上的話,在cleint中也要加上-->
<service android:name=".MessengerService"
android:exported="true"
android:permission="com.lixxy.client.service">
</service>
客戶端
首先要繫結服務端的service,然後在ServiceConnection中就可以通過IBinder傳送訊息.
@Override
//bind方法需要三個引數,intent,ServiceConnection,flags
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
//Intent
//由於服務端和客服端是兩個APP,所以不能通過Intent intent = new //Intent(this,MessengerService.class);獲取Intent
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.lixxy.service","com.lixxy.service.MessengerService"));
//private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Bundle bundle = new Bundle();
bundle.putString("client", "Hello,Services");
Message message = Message.obtain();
message.what = 100;
message.setData(bundle);
//如果客戶端同時要接受伺服器發的訊息,需要加這句
message.replyTo = mMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "連線失敗");
}
};
如果客戶端同時要接受伺服器發的訊息,也要建立一個Handler處理訊息,然後通過這個Handler來建立Messenger物件.
完整的客戶端程式碼如下
package com.lixxy.client;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.nfc.Tag;
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.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private final Messenger mMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 200:
//獲取service傳送的訊息
Log.e(TAG, msg.getData().getString("service"));
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.mBtnBind);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//由於服務端和客服端是兩個APP,所以不能通過
// Intent intent = new //Intent(this,MessengerService.class)獲取Intent
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.lixxy.service", "com.lixxy.service.MessengerService"));
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
});
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Bundle bundle = new Bundle();
bundle.putString("client", "Hello,Services");
Message message = Message.obtain();
message.what = 100;
message.setData(bundle);
//如果客戶端同時要接受伺服器發的訊息,需要加這句
message.replyTo = mMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "連線失敗");
}
};
}
注意:如果服務端的service中加了android:permission:“xxx.xxx.xxx”,那麼在客戶端的AndroidManifest也要加入許可權,不然會報錯Not allowed to bind to service Intent
<permission android:name="com.lixxy.client.service" />
<uses-permission android:name="com.lixxy.client.service" />