Android 进程间通讯是非常重要的知识点,其实他的实现方式有很多种比如,使用Bundle,使用文件共享,使用AIDL,使用ContentProvider,Socket
今天的通信方式,我们采用另外一种传递信息比较方便方式,Messenger。
先看个图
可以看到Client向Server发送一条消息,由服务端的Hanlder来接收,服务端接收到消息再发送给客户端,由客户端的Hanlder接收处理,从而形成一个通信流程。
来个例子
app1客户端–ServerA
public class MessengerService extends Service {
private final int SMS_FORM_CLINET=1111;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private Messenger mMessenger=new Messenger(new MessageHandler());
private class MessageHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
//来自客户端
case SMS_FORM_CLINET:
int arg2 = msg.arg2;
String serverMsg="你好,"+arg2+"号";
Message message = Message.obtain(null, SMS_FORM_CLINET);
message.arg1=msg.arg1;
Bundle bundle=new Bundle();
bundle.putString("msg",serverMsg);
message.setData(bundle);
Messenger client = msg.replyTo;
try {
Thread.sleep(2000);
client.send(message);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
super.handleMessage(msg);
}
}
}
清单文件
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="com.liv.aidl.calc"></action>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
app2客户端–ClientB
public class MainActivity extends AppCompatActivity {
private ServiceConnection mConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(MainActivity.this,"成功",Toast.LENGTH_LONG).show();
mServer = new Messenger(service);
isConn = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(MainActivity.this,"失败",Toast.LENGTH_LONG).show();
mServer=null;
isConn = false;
}
};
Messenger messenger=new Messenger(new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case SMS_FORM_CLINET:
TextView tv = (TextView) rootView.findViewById(msg.arg1);
String msg1 = msg.getData().getString("msg");
tv.setText(tv.getText()+"-->"+msg1);
break;
}
}
});
private final int SMS_FORM_CLINET=1111;
private Messenger mServer;
private boolean isConn;
private int id=100;
private LinearLayout rootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent();
intent.setAction("com.liv.aidl.calc");
intent.setPackage("livesun.servera");
bindService(intent,mConnection,Context.BIND_AUTO_CREATE);
rootView = (LinearLayout) findViewById(R.id.root);
findViewById(R.id.binder).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int textId=id++;
int count=(int) (Math.random() * 100);
TextView tv = new TextView(MainActivity.this);
tv.setText( "服务端,我是"+count+"号...");
tv.setId(textId);
rootView.addView(tv);
Message message = Message.obtain(null, SMS_FORM_CLINET,textId,count);
message.replyTo=messenger;
if(isConn){
try {
mServer.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
效果如下
点击看下Messenger的构造方法
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
怎么样,是不是感觉特别熟悉,我们可以很明显看出是AIDL的封装,其实仔细看下源码,Messenger确实是根据AIDL来做的,同时Messenger是以串行的方式处理客户端发送来的消息,不能像AIDL一样处理并发请求,而且就像信使这个名字一样,Messenger只负责传递信息,如果想跨进程调用服务端的某个方法,Messenger是做不到的。