安卓IPC(进程间通信)之Messenger基本使用

来源:互联网 发布:ubuntu 14.04 下载 编辑:程序博客网 时间:2024/06/05 02:21

首先我们来看下客户端的写法:

public class MainActivity extends AppCompatActivity {    //日志Tag    private static final String TAG = "Messenger-client";    //消息标识    private static final int WHAT = 2;    //是否连接成功(ServiceConnected);    private boolean iscon;    //声明服务端messenger    private Messenger sM;    //创建客服端messenger    private Messenger cM = new Messenger(new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what){                case 3:                    Bundle data = msg.getData();                    Player lakers = (Player) data.getSerializable("lakers");                    Log.d(TAG, lakers.toString()+"--"+msg.arg1);                    break;            }        }    });    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //连接成功为true              iscon = true;            //从服务端返回的IBinder实例中拿到服务端的messenger              sM = new Messenger(service);        }        @Override        public void onServiceDisconnected(ComponentName name) {            //连接失败为false             iscon = false;            //连接失败时把服务端messenger致为空            sM = null;        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void bindRemoteService(View view) {        Intent service = new Intent();        //service.setAction("com.qf.yanxun.messengerserver.MyService");        service.setClassName("com.qf.yanxun.messengerserver","com.qf.yanxun.messengerserver.MyService");        boolean b = bindService(service, conn, BIND_AUTO_CREATE);        if(b){            Toast.makeText(this,"连接远程服务成功",Toast.LENGTH_SHORT).show();        }else {            Toast.makeText(this,"连接远程服务失败",Toast.LENGTH_SHORT).show();        }    }    public void sendxx(View view) {        //从消息池里面返回一个空消息        Message cme = Message.obtain();        cme.arg1 = 23;        cme.arg2 = 2;        cme.what = WHAT;        Bundle bundle = new Bundle();        bundle.putString("cle","詹姆斯+欧文+乐福");        cme.obj = bundle;//由于Binder事物传递的数据被称为包裹(Parcel),必须实现Parcelable接口,否则无法在应用间通信        //所以如果要在消息中携带数据,可以使用Bundle,因为bundle类已经实现了Parcelable接口        bundle.putSerializable("NBA",new Player("詹姆斯",32));        //指明发送方地址进而让服务端回信        cme.replyTo = cM;        cme.setData(bundle);        try {            //用服务端的messenger发消息给服务端            sM.send(cme);        } catch (RemoteException e) {            e.printStackTrace();        }    }    @Override    protected void onDestroy() {        super.onDestroy();        //当活动退出时先判断当前是否连接如连接服务则unbindService        if(iscon){            unbindService(conn);        }    }}

这里的注释已经很详细了,简单讲下具体步骤:

1.主布局代码不用说了很简单就是放了两个按钮,我们重点来看下这两个按钮的监听方法

#bindRemoteService

可以看到这里面主要是一个bindService()方法,关于这个方法的作用我想不用多说了吧!我们来看下里面的参数:

一.由于是跨进程所以我们不能显示指定哪个服务这里用了一个intent.setClassName()方法来指定里面两个参数其一服务端的包名,其二是service的全类名

二.这才是Messenger跨进程通信的重点ServiceConnection里面有两个方法当连接服务成功时回调第一个当然是失败就是第二个,我们主要关注第一个方法onserviceconnected()

它的第二参数是核心就是服务端返回过IBinder接口实例我就是通过这个实例拿到服务端的messenger的随后才能进行一系列操作


说到这里我们来看下服务端的写法:

public class MyService extends Service{    private static final String TAG = "Messenger-server";     //创建服务端Messenger;    private Messenger sM = new Messenger(new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what){                case 2:                    Bundle b = (Bundle) msg.obj;                    String cle = b.getString("cle");                    Bundle data = msg.getData();                    Player nba = (Player) data.getSerializable("NBA");                    String s = msg.replyTo.toString();                    Log.d(TAG,cle+"--"+nba.toString()+"--"+msg.arg1+"--"+msg.arg2+"--来自:"+s);                    Message sMe = Message.obtain();                    sMe.arg1 = msg.arg1+msg.arg2;                    sMe.what = 3;                    Bundle bundle = new Bundle();                    bundle.putSerializable("lakers",new Player("科比",38));                    sMe.setData(bundle);                    try {                        //用客户端指明的发送地址给他回信                        msg.replyTo.send(sMe);                    } catch (RemoteException e) {                        e.printStackTrace();                    }                    break;            }        }    });    public IBinder onBind(Intent intent) {        return sM.getBinder();    }}

大家可以注意到onBind()方法返回了什么:其实最终不管怎么样都是跟IBinder有关这里就不展开说了 通过这个方法最终客户端能得到服务端的messenger,

Messenger做到通信就是客户端和服务端都能拿到各自的messenger实例 而服务端拿到客户端messenger是通过客户端的msg.replyto()方法

其他不都说了注释都很清楚  当然了那个bundle里面放对象 不用多说Player肯定是要实现Serializable接口的!好了就这样吧  本人菜鸟一枚 希望与大家共成长


转载请注明出处:http://blog.csdn.net/qq_35189116/article/details/70338200


0 0
原创粉丝点击