赞
踩
项目中常用到的进程间通信更多是用AIDL,在前阵子复习的时候才了解还有 Messenger 这种方法。既然要学习就记录下,以后要用的时候才能快速的掌握。
Messenger 是一种轻量级的IPC方案,它的底层实现是AIDL,可以在不同进程中传递 Message 对象,它一次只处理一个请求,在服务端不需要考虑线程同步的问题,服务端不存在并发执行的情况。
Public constructors | |
---|---|
Messenger(Handler target) Create a new Messenger pointing to the given Handler. | |
Messenger(IBinder target) Create a Messenger from a raw IBinder, which had previously been retrieved with |
3.1 客户端步骤:
3.1.1 创建一个handler对象,并实现 handleMessage() 方法,用户接收客户端的消息。
3.1.2 创建Messenger ,封装handler。
3.1.3 用Messenger的 getBinder() 方法获取一个IBinder对象,通过 onBind 返回给客户端。
服务端的Service:
- package cn.zzw.messenger.server;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.Messenger;
- import android.os.RemoteException;
- import android.util.Log;
-
- public class MessengerService extends Service {
-
- private static final String TAG = "MessengerService";
- private MessengerHandler mHandler = new MessengerHandler();
- private Messenger mMessenger = new Messenger(mHandler);
- private static final int MSG_SUM = 10086;
-
- private class MessengerHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- if(msg.what==MSG_SUM)
- {
- Log.e(TAG,"handleMessage");
- try {
- int arg1 = msg.arg1;
- int arg2=msg.arg2;
- Message msgToClient=Message.obtain(msg);
- msgToClient.arg1=arg1+arg2;
- msg.replyTo.send(msgToClient);
- } catch (RemoteException e) {
-
- }
- }
-
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mMessenger.getBinder();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mHandler.removeCallbacksAndMessages(null);
- }
- }
3.2 客户端步骤:
3.2.1 在 Activity 中绑定服务。
3.2.2 创建ServiceConnection并在其中使用 IBinder 将 Messenger实例化
3.2.3 使用Messenger向服务端发送消息
客户端主要代码:
- package cn.zzw.messenger.client;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.Messenger;
- import android.os.RemoteException;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- import android.widget.Toast;
-
- public class MainActivity extends AppCompatActivity {
- private static final String TAG = "MessengerClient";
- private TextView mTv;
- private Messenger mService;
- private static final int MSG_SUM = 10086;
- private MessengerHandler mHandler = new MessengerHandler();
- private Messenger mMessenger = new Messenger(mHandler);
-
- private class MessengerHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
-
- if(msg.what==MSG_SUM)
- {
- Log.e(TAG,"handleMessage");
- int arg1 = msg.arg1;
- Log.e(TAG,"handleMessage:"+arg1);
- Toast.makeText(MainActivity.this,"The Result is "+arg1,Toast.LENGTH_SHORT).show();
- }
-
- }
- }
- private ServiceConnection conn=new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- //获取服务端关联的Messenger对象
- mService = new Messenger(iBinder);
- Log.e(TAG,"onServiceConnected");
- }
-
- @Override
- public void onServiceDisconnected(ComponentName componentName) {
- Log.e(TAG,"onServiceDisconnected");
- mService=null;
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- bindToServserService();
- mTv = findViewById(R.id.mTv);
- findViewById(R.id.mBtn_cal).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Message msg = Message.obtain(null, MSG_SUM, 10, 500);
- msg.replyTo = mMessenger;
- if(null!=mService)
- {
- //往服务端发送消息
- try {
- Log.e(TAG,"mService.send");
- mService.send(msg);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- }
- });
- }
-
- /*
- * 绑定服务端的Service
- */
- private void bindToServserService() {
- Intent intent=new Intent();
- intent.setPackage("cn.zzw.messenger.server");
- intent.setAction("CN.ZZW.MESSENGER.SERVER");
- bindService(intent,conn,BIND_AUTO_CREATE);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unbindService(conn);
- mHandler.removeCallbacksAndMessages(null);
- }
- }
client端的log:
- E/MessengerClient: mService.send
- E/MessengerClient: mService.send
- handleMessage
- handleMessage:510
- E/MessengerClient: handleMessage
- handleMessage:510
Server端的log:
- E/MessengerService: handleMessage
- E/MessengerService: handleMessage
- E/MessengerService: handleMessage
- E/MessengerService: handleMessage
- E/MessengerService: handleMessage
先看下 Messenger 的源码,代码行数非常少:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/Messenger.java
- /*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package android.os;
-
- /**
- * Reference to a Handler, which others can use to send messages to it.
- * This allows for the implementation of message-based communication across
- * processes, by creating a Messenger pointing to a Handler in one process,
- * and handing that Messenger to another process.
- *
- * <p>Note: the implementation underneath is just a simple wrapper around
- * a {@link Binder} that is used to perform the communication. This means
- * semantically you should treat it as such: this class does not impact process
- * lifecycle management (you must be using some higher-level component to tell
- * the system that your process needs to continue running), the connection will
- * break if your process goes away for any reason, etc.</p>
- */
- public final class Messenger implements Parcelable {
- private final IMessenger mTarget;
-
- /**
- * Create a new Messenger pointing to the given Handler. Any Message
- * objects sent through this Messenger will appear in the Handler as if
- * {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
- * been called directly.
- *
- * @param target The Handler that will receive sent messages.
- */
- public Messenger(Handler target) {
- mTarget = target.getIMessenger();
- }
-
- /**
- * Send a Message to this Messenger's Handler.
- *
- * @param message The Message to send. Usually retrieved through
- * {@link Message#obtain() Message.obtain()}.
- *
- * @throws RemoteException Throws DeadObjectException if the target
- * Handler no longer exists.
- */
- public void send(Message message) throws RemoteException {
- mTarget.send(message);
- }
-
- /**
- * Retrieve the IBinder that this Messenger is using to communicate with
- * its associated Handler.
- *
- * @return Returns the IBinder backing this Messenger.
- */
- public IBinder getBinder() {
- return mTarget.asBinder();
- }
-
- /**
- * Comparison operator on two Messenger objects, such that true
- * is returned then they both point to the same Handler.
- */
- public boolean equals(Object otherObj) {
- if (otherObj == null) {
- return false;
- }
- try {
- return mTarget.asBinder().equals(((Messenger)otherObj)
- .mTarget.asBinder());
- } catch (ClassCastException e) {
- }
- return false;
- }
-
- public int hashCode() {
- return mTarget.asBinder().hashCode();
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeStrongBinder(mTarget.asBinder());
- }
-
- public static final Parcelable.Creator<Messenger> CREATOR
- = new Parcelable.Creator<Messenger>() {
- public Messenger createFromParcel(Parcel in) {
- IBinder target = in.readStrongBinder();
- return target != null ? new Messenger(target) : null;
- }
-
- public Messenger[] newArray(int size) {
- return new Messenger[size];
- }
- };
-
- /**
- * Convenience function for writing either a Messenger or null pointer to
- * a Parcel. You must use this with {@link #readMessengerOrNullFromParcel}
- * for later reading it.
- *
- * @param messenger The Messenger to write, or null.
- * @param out Where to write the Messenger.
- */
- public static void writeMessengerOrNullToParcel(Messenger messenger,
- Parcel out) {
- out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
- : null);
- }
-
- /**
- * Convenience function for reading either a Messenger or null pointer from
- * a Parcel. You must have previously written the Messenger with
- * {@link #writeMessengerOrNullToParcel}.
- *
- * @param in The Parcel containing the written Messenger.
- *
- * @return Returns the Messenger read from the Parcel, or null if null had
- * been written.
- */
- public static Messenger readMessengerOrNullFromParcel(Parcel in) {
- IBinder b = in.readStrongBinder();
- return b != null ? new Messenger(b) : null;
- }
-
- /**
- * Create a Messenger from a raw IBinder, which had previously been
- * retrieved with {@link #getBinder}.
- *
- * @param target The IBinder this Messenger should communicate with.
- */
- public Messenger(IBinder target) {
- mTarget = IMessenger.Stub.asInterface(target);
- }
- }
这时候我们在回头看两个构造方法:
- 1. public Messenger(Handler target) {
- mTarget = target.getIMessenger();
- }
-
-
- 2. public Messenger(IBinder target) {
- mTarget = IMessenger.Stub.asInterface(target);
- }
两个构造方法内部都是初始化对象 mTarget:
private final IMessenger mTarget;
再看看 IMessenger,是一个AIDL文件:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/IMessenger.aidl
- /* //device/java/android/android/app/IActivityPendingResult.aidl
- **
- ** Copyright 2007, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
- package android.os;
-
- import android.os.Message;
-
- /** @hide */
- oneway interface IMessenger {
- void send(in Message msg);
- }
在看看Handler 中的部分代码:
- 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);
- }
- }
从以上代码,可以看出Messenger又跟Binder联系起来了。 最终还是AIDL文件来完成的,只不过Messenger进行了深度的封装AIDL,使用起来更简单。
最后,附上文中的示例代码:https://download.csdn.net/download/zzw0221/11260381
参考:
https://blog.csdn.net/hzw2017/article/details/81090319
https://www.jianshu.com/p/48e212d1fde4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。