博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Messenger实现Android IPC
阅读量:6611 次
发布时间:2019-06-24

本文共 4332 字,大约阅读时间需要 14 分钟。

hot3.png

当Service不需要支持并发操作时Messenger会非常有用。Messenger类使用Handler执行每个传入的消息,所有客户端的调用都按顺序运行在同一个线程上,这和AIDL是有区别的,AIDL每个客户端对应一个线程。使用Messenger类还能避免AIDL文件带来的问题,并可以方便地为客户端提供异步消息API。虽然没有那么强大,但该类有时候会很有效,因为它更容易在客户端和Service实现。

下面的例子展示了如何使用Messenger类来提供异步API。首先在onCreate()方法中创建Messenger,然后在onBind()方法中返回Binder对象。当Messenger接受到消息时,它使用存储在replyTo成员变量里的Messenger对象响应客户端的请求。

public class MessengerService extends Service {    private Handler mMessageHandler;    private Messenger mMessenger;    public MessengerService() {    }
    @Override    public IBinder onBind(Intent intent) {        return this.mMessenger.getBinder();    }
    @Override    public void onCreate() {        super.onCreate();        HandlerThread handlerThread=new HandlerThread("MessengerService");        handlerThread.start();        this.mMessageHandler=new Handler(handlerThread.getLooper(),new MyhandlerCallback());        this.mMessenger=new Messenger(this.mMessageHandler);    }
    @Override    public void onDestroy() {        super.onDestroy();        this.mMessageHandler.getLooper().quit();    }
    private class MyhandlerCallback implements Handler.Callback{        @Override        public boolean handleMessage(Message msg) {            boolean delivered=false;            switch (msg.what){                case 0:
//执行相应的任务                    delivered=true;                    break;                case 1:
//执行相应的任务                    break;            }            Message reply=Message.obtain(null,2);//生成消息            try {                msg.replyTo.send(reply);//反馈消息            } catch (RemoteException e) {                e.printStackTrace();            }            return true;        }    }}
下例中,客户端首先绑定到Service,然后使用IBinder作为参数构建一个Messenger对象,作为运行在远程Service中的Messenager的代理。当向Service发送消息时,也可以设置Message对象的replyTo属性。
public class MainActivity extends Activity implements ServiceConnection {    private Button start;    private Messenger mRemoteMessenger;    private Messenger mReplyMessenger;    private Handler mReplyHandler;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        this.start=(Button)findViewById(R.id.start);        HandlerThread handlerThread=new HandlerThread("ReplyMessenger");        handlerThread.start();        this.mReplyHandler=new Handler(handlerThread.getLooper(),new ReplyHandlerCallback());        this.mReplyMessenger=new Messenger(this.mReplyHandler);    }
    @Override    protected void onResume() {        super.onResume();        bindService(new Intent("com.example.liyuanjing.myapplication.MESSENGER_SERVICE"),this,BIND_AUTO_CREATE);    }
    @Override    protected void onPause() {        super.onPause();        unbindService(this);    }
    @Override    protected void onDestroy() {        super.onDestroy();        this.mReplyHandler.getLooper().quit();    }
    public void onSendTextPressed(View v){        Message message=Message.obtain();        message.what=0;        Bundle bundle=new Bundle();        bundle.putInt("key",1);        message.obj=bundle;        message.replyTo=mReplyMessenger;        try {            mRemoteMessenger.send(message);        } catch (RemoteException e) {            e.printStackTrace();        }    }
    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        this.mRemoteMessenger=new Messenger(service);        this.start.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                onSendTextPressed(v);            }        });    }
    @Override    public void onServiceDisconnected(ComponentName name) {        this.mRemoteMessenger=null;    }    private class ReplyHandlerCallback implements Handler.Callback{        @Override        public boolean handleMessage(Message msg) {            switch (msg.what){                case 2:                    Toast.makeText(MainActivity.this,"接受到了",Toast.LENGTH_LONG).show();                    break;            }            return true;        }    }}
   
注意必须用Bundle传递常规类型数据,否则会报错:

java.lang.RuntimeException: Can't marshal non-Parcelable objects across processes.

因为Binder事务传递的数据被称为包裹(Parcel),必须实现Parcelable接口,否则无法在两个应用之间进行通信。之所以用Bundle传递是因为该类实现了Parcelable接口。当然如果要传递类也必须实现该接口。

转载于:https://my.oschina.net/liyuanjinglyj/blog/415736

你可能感兴趣的文章
配置Tomcat数据源
查看>>
黑鹰坠落 感
查看>>
CopyOnWriteArrayList
查看>>
我的友情链接
查看>>
JAVA的StringBuffer类
查看>>
Douyu
查看>>
Citrix Receiver For Android V2.1发布
查看>>
scrapy深入学习----(4)
查看>>
plsql使用引号,输出空行
查看>>
Mesos统一容器管理技术简介
查看>>
我的友情链接
查看>>
Docker容器互联的几个基本方法
查看>>
WebService - Client调用(Axis2-Document)
查看>>
老男孩教育每日一题-day57-脑洞神探之tmp目录的下的备份文件突然没了,谁来背锅?...
查看>>
Docker下载Redis镜像并运行容器
查看>>
kvm cgroup的使用
查看>>
分享申请IDP账号的过程,包含duns申请的分享
查看>>
参加PMP考试须知
查看>>
java学习
查看>>
Android studio教程与问题汇总
查看>>