查看Handler源码的时候会看到有个IMessenger类型的变量mMessenger,从名字来看是一个接口,然后顺着找下去可以看到一个getIMessenger()方法如下:
可以找到它的实现类是MessengerImpl,这个类Handler的内部类继承了IMessenger.Stub,这个貌似跟IPC有关系,应该有一个IMessenger.aidl文件。查看android.os包,果然找到了这个文件,有一个send方法,参数是Message。
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) { return mMessenger; }
mMessenger = new MessengerImpl(); return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
可以找到它的实现类是MessengerImpl,这个类Handler的内部类继承了IMessenger.Stub,这个貌似跟IPC有关系,应该有一个IMessenger.aidl文件。查看android.os包,果然找到了这个文件,有一个send方法,参数是Message。
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
可以推断Handler支持跨进程通信,这时候就我们的另一个主角Messenger就出现了,Messenger实现Parcelable,上主要代码:
public final class Messenger implements Parcelable {
private final IMessenger mTarget;
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
public IBinder getBinder() {
return mTarget.asBinder();
}
}
mTarget就是那个Handler中看到的IMessenger。那么如何使用呢?首先创建服务端工程Server,创建Service类:
public class MessegerService extends Service{
Messenger mMessenger=null;
Handler mHanlder=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
if(mMessenger!=null){
Message message=Message.obtain();
Bundle bundle=new Bundle();
bundle.putString("key","IPC服务端message");
message.setData(bundle);
message.what=2;
try {
msg.replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
};
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
Log.d("messengerService","onCreate");
if(mMessenger==null){
mMessenger=new Messenger(mHanlder);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
然后创建客户端工程,写一个连接管理类MessengerManager.java:
public class MessengerManager implements ServiceConnection{
private final static String serviceName="zs.android.ipc.service.MessegerService";
Messenger mMessenger;
Handler mHandler;
boolean isBinding=false;
BindCallback mBindCallback;
public static MessengerManager instance;
private MessengerManager(){
}
public static final MessengerManager getInstance(){
if(instance==null){
synchronized (MessengerManager.class) {
if(instance==null){
instance=new MessengerManager();
}
}
}
return instance;
}
public void setBindCallback(BindCallback bindCallback){
mBindCallback=bindCallback;
}
/**
* 绑定Service
* @param context
*/
public void bindService(Context context){
Intent intent=new Intent();
//intent.setClassName(context, serviceName);
intent.setClassName("zs.android.zs", serviceName);
context.bindService(intent, this, Context.BIND_AUTO_CREATE);
}
/**
* 解绑Service
*/
public void unBindService(Context context){
if(isBinding){
context.unbindService(this);
}
}
/**
* 是否绑定完成
* @return
*/
public boolean isBinding(){
return isBinding;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger=new Messenger(service);
isBinding=true;
if(mBindCallback!=null){
mBindCallback.bindsucess();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
if(mBindCallback!=null){
mBindCallback.bindfail();
}
isBinding=false;
destroySelf();
}
public void destroySelf(){
mMessenger=null;
}
public void getServerData(Message message){
if(mMessenger!=null){
try {
mMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public interface BindCallback{
void bindsucess();
void bindfail();
}
}
然后客户端使用:
public class MainActivity extends FragmentActivity {
private ImageView image;
private TextView text01,text02;
Handler hanlder=new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 2:
Bundle bundle=msg.getData();
if(bundle!=null){
Toast.makeText(getApplicationContext(), "hanlder+"+bundle.getString("key"), Toast.LENGTH_SHORT).show();;
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image=(ImageView)findViewById(R.id.image);
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(MessengerManager.getInstance().isBinding()){
Message message=Message.obtain();
message.replyTo=new Messenger(hanlder);
message.what=1;
MessengerManager.getInstance().getServerData(message);
}else{
Toast.makeText(getApplicationContext(), "未绑定服务", Toast.LENGTH_SHORT).show();
}
}
});
MessengerManager.getInstance().bindService(getApplicationContext());
MessengerManager.getInstance().setBindCallback(new BindCallback() {
@Override
public void bindsucess() {
Toast.makeText(getApplicationContext(),"绑定成功",Toast.LENGTH_SHORT).show();
}
@Override
public void bindfail() {
Toast.makeText(getApplicationContext(),"绑定失败",Toast.LENGTH_LONG).show();
}
});
startService(new Intent(this, DataService.class));
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
MessengerManager.getInstance().unBindService(getApplicationContext());
}
}
点击image,给服务端程序发送请求命令,会收到服务端的反馈信息在客户端的Handler中处理。
使用中需要注意的问题:
1、如果服务端和客户端需要互相通讯,那么客户端在发送Message的时候需要新建一个messenger=Messenger(Handler handler),然后mesager.replyTo=messenger,发送给服务端。
2、绑定Service需要使用到服务端程序的包名,隐试启动也需要制定服务端的包名。
3、绑定Service传入的Context使用相同的context,否则解绑的时候会未注册的报错。