Android之基于message的进程间通信Messenger

使用Messenger:

Messenger 可以在不同的进程传递 Message 对象,而我们可以在 Message 对象中放入我们所需要的数据,这样就能实现进程间通信了。首先我们来看一个图了解一下:

由图可以看出,我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。

以下是如何使用Messenger的步骤:

服务端接收客户端数据:

1. Service需要实现一个Hanlder,用以处理从客户端收到的消息

2.用该Handler创建一个Messenger对象,Messenger对象内部会引用该Handler对象

3. 用创建好的Messenger对象获得一个IBinder实例,并且将该IBinder通过Service的onBind方法返回给各个客户端

 

客户端向服务端发送数据:

4. 客户端通过收到的IBinder对象实例化一个Messenger对象,该Messenger内部指向Service中的Handler。客户端通过该Messenger对象就可以向Service中的Hanlder发送消息。

5. Service中的Hanlder收到消息后,在Handler中的handleMessage方法中处理消息。

6. 通过上面的第4步与第5步,就完成了客户端向Service发送消息并且Service接收到消息的单向通信过程,即客户端 -> Service。

 

如果要实现Service向客户端回消息的通信过程,即Service -> 客户端,那么前提是在客户端中也需要像Service一样内部维护有一个指向Handler的Messenger。当在第4步中客户端向Service发送信息时,将Message的replyTo属性设置为客户端自己的Messenger。这样在第5步Service在Handler的handleMessage中处理收到的消息时,可以通过Message的Messenger再向客户端发送Message,这样客户端内维护的Handler对象就会收到来自于Service的Message,从而完成Service向客户端发送消息且客户端接收到消息的通信过程。

具体实例:

1)服务端代码:

public class MessengerService extends Service {
    private static final String TAG = "MessengerService";

    // 消息处理messengerHandler,处理来自客户端的消息
    private ServiceMessengerHandler messengerHandler = new ServiceMessengerHandler();

    // 指向handler的服务端Messenger
    private Messenger mServiceMessenger = new Messenger(messengerHandler);
    public MessengerService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mServiceMessenger.getBinder();
    }

    public static class ServiceMessengerHandler extends Handler{

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            // 取出客户端的消息内容
            Bundle clientBundle = msg.getData();
            String clientMessage = clientBundle.getString("client");
            Log.i(TAG, "客户端的消息是:" + clientMessage);

            // 新建一个Message对象,作为回复客户端的对象(Service回复的消息)
            Message serviceToClientMsg = Message.obtain();
            Bundle serviceBundle = new Bundle();
            serviceBundle.putString("service", "你好,客户端很高兴认识你!");
            serviceToClientMsg.setData(serviceBundle);

            // 获取客户端携带过来的Messenger对象
            Messenger mClientMessenger = msg.replyTo;
            try {
                // 回复消息给客户端
                mClientMessenger.send(serviceToClientMsg);
            } catch(RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}

2)客户端代码

public class MessengerActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MessengerActivity";

    // 客户端的消息处理器
    private ClientMessengerHandler clientMessengerHandler = new ClientMessengerHandler();

    // 指向handler的客户端的Messenger
    private Messenger mClientMessenger = new Messenger(clientMessengerHandler);

    private static class ClientMessengerHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            Bundle serviceBundle = msg.getData();
            String serviceMessage = serviceBundle.getString("service");
            Log.i(TAG, "服务端回复的消息是:" + serviceMessage);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
    }

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bindService:
                Intent intent = new Intent(this, MessengerService.class);
                bindService(intent, mConnection, BIND_AUTO_CREATE);
                break;
            case R.id.unBindService:
                unbindService(mConnection);
                break;
            default:
                break;

        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            // 获取服务端关联的Messenger对象
            Messenger mServiceMessenger = new Messenger(iBinder);

            // 创建客户端向服务端传递消息的Message
            Message clientToServiceMsg = Message.obtain();
            Bundle clientBundle = new Bundle();
            clientBundle.putString("client", "你好,服务器,我是客户端!");
            clientToServiceMsg.setData(clientBundle);

            // 在message中添加一个服务端回复客户端的客户端Messenger对象
            clientToServiceMsg.replyTo = mClientMessenger;
            try {
                mServiceMessenger.send(clientToServiceMsg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

(3)客户端布局文件

 

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MessengerActivity">

    <Button
        android:id="@+id/bindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/unBindService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

posted @ 2019-08-05 10:02  Vitality  阅读(767)  评论(0编辑  收藏  举报