本文主要是介绍认识Messenger,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【Messenger】==================================================
@概述:
·实现跨进程的Handler消息传递和处理;
·其实现原理与AIDL相同,即绑定远程Service,跨进程获得Binder对象,进而实现通信;
·相比AIDL的优势为,Messenger可以通过Message和Bundle实现【对象型参数】的跨进程传递;
----------------------------------------
@注意事项:
·绑定远程服务的意图,必须指定包名;
·使用Messenger发送消息时,字符串和对象必须放在Bundle中;
·如须发送对象,对象类必须要实现Serializable接口;
·如须发送对象,则服客两端对象类的包名和内容都必须一致;
----------------------------------------
@服务端开发流程:
·定义Service,在初始化时,定义Messenger对象,在其内置Handler中实现客户端消息处理逻辑:
@Override
public void onCreate() {
super.onCreate();
/**
* 初始化服务端信使(将来往家里送信),内置Handler用于处理来信
*/
sMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
//处理客户端消息
int arg1 = msg.arg1;
int arg2 = msg.arg2;
Bundle cBundle = msg.getData();
String str = cBundle.getString("string");
User cUser = (User) cBundle.getSerializable("serializable");
Log.d(TAG, "收到客户端来信:1/2/s/u" + arg1 + "/" + arg2 + "/" + str + "/" + cUser);
//使用客户端信使回信
cMessenger = msg.replyTo;//取出客户端Messenger
Message replyMsg = Message.obtain();
replyMsg.arg1 = arg1 + arg2;
Bundle bundle = new Bundle();
bundle.putString("string", "this is reply from server");
bundle.putSerializable("serializable", new User("serverGirl", 20));
replyMsg.setData(bundle);
try {
cMessenger.send(replyMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
·在onBind方法中返回本地Messenger对象的内置Binder:
@Override
public IBinder onBind(Intent intent) {
return sMessenger.getBinder();//将我方信使的Binder的返回给远程应用,远程应用可以通过该Binder还原出sMessenger(代理)
}
·如须向客户端发送回复消息,可以从客户端Message中获取客户端Messenger,并用其发送回复消息:
sMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
//处理客户端消息
...
//使用客户端信使回信
cMessenger = msg.replyTo;//取出客户端Messenger
Message replyMsg = Message.obtain();
replyMsg.arg1 = arg1 + arg2;
...
try {
cMessenger.send(replyMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
----------------------------------------
@客户端开发流程:
·绑定远程服务:
Intent intent = new Intent("com.mobiletrain.messenger.action.myservice");
intent.setPackage("com.mobiletrain.messenger");//包名是必须的!
bindService(intent, conn,BIND_AUTO_CREATE);
·在ServiceConnnection对象中获取服务端Binder对象,并用其构造向服务端发送消息的Messenger:
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
sMessenger = new Messenger(binder);//还原服务端信使
Toast.makeText(MainActivity.this, "远程服务连接成功!", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(MainActivity.this, "远程服务异常断开!", Toast.LENGTH_SHORT).show();
}
};
·使用构造好的服务端Messenger向服务端发送消息,消息的replyTo设置为我方Messenger:
Message message = Message.obtain();
message.replyTo = cMessenger;//植入我方信使
message.arg1 = 56;
message.arg2 = 78;
Bundle bundle = new Bundle();
bundle.putString("string", "this is msg from client");
bundle.putSerializable("serializable", new User("clientBoy", 30));
message.setData(bundle);
try {
sMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
·创建我方Messenger实例,并在其内置Handler中实现消息处理逻辑,将来用于处理服务端发来的消息:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = ((TextView) findViewById(R.id.tv));
cMessenger = new Messenger(new Handler(){
@Override
public void handleMessage(Message msg) {
//处理服务端来信
int sum = msg.arg1;
tv.setText("服务端结果:"+sum);
Bundle bundle = msg.getData();
String str = bundle.getString("string");
User user = (User) bundle.getSerializable("serializable");
Toast.makeText(MainActivity.this, str+"/"+user, Toast.LENGTH_LONG).show();
}
});
}
这篇关于认识Messenger的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!