深入剖析Android四大组件(四)——Messenger实现Android IPC

简介: 深入剖析Android四大组件(四)——Messenger实现Android IPC

当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
        android:name=".MessengerService"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="com.example.liyuanjing.myapplication.MESSENGER_SERVICE"/>
        </intent-filter>
    </service>

下例中,客户端首先绑定到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接口。当然如果要传递类也必须实现该接口。

相关文章
|
1月前
|
存储 设计模式 数据库
构建高效的安卓应用:探究Android Jetpack架构组件
【4月更文挑战第20天】 在移动开发的世界中,构建一个既高效又可维护的安卓应用是每个开发者追求的目标。随着Android Jetpack的推出,Google为开发者提供了一套高质量的库、工具和指南,以简化应用程序开发流程。本文将深入探讨Jetpack的核心组件之一——架构组件,并展示如何将其应用于实际项目中,以提升应用的响应性和稳定性。我们将通过分析这些组件的设计原则,以及它们如何协同工作,来揭示它们对于构建现代化安卓应用的重要性。
|
1月前
|
Android开发
Android四大组件详解2
Android四大组件详解
35 1
|
1月前
|
存储 监控 数据可视化
Android四大组件详解1
Android四大组件详解
60 0
|
1月前
|
设计模式 Android开发
[Android 四大组件] --- BroadcastReceiver
[Android 四大组件] --- BroadcastReceiver
40 0
|
1月前
|
Android开发 算法 架构师
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
|
1月前
|
Android开发 缓存 双11
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
|
1月前
|
Java 开发工具 Android开发
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
21 4
|
2天前
|
API Android开发 开发者
`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView
【6月更文挑战第26天】`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView。它提供高效的数据视图复用,优化的布局管理,支持多种布局(如线性、网格),并解耦数据、适配器和视图。RecyclerView的灵活性、性能(如局部刷新和动画支持)和扩展性使其成为现代Android开发的首选,特别是在处理大规模数据集时。
15 2
|
12天前
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
|
21天前
|
XML Android开发 数据格式
【Android UI】中间对齐UI组件
【Android UI】中间对齐UI组件
11 1