700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android 进程间通信:Messenger

Android 进程间通信:Messenger

时间:2021-11-01 22:07:23

相关推荐

Android 进程间通信:Messenger

1.概述

项目中常用到的进程间通信更多是用AIDL,在前阵子复习的时候才了解还有Messenger这种方法。既然要学习就记录下,以后要用的时候才能快速的掌握。

Messenger是一种轻量级的IPC方案,它的底层实现是AIDL,可以在不同进程中传递 Message 对象,它一次只处理一个请求,在服务端不需要考虑线程同步的问题,服务端不存在并发执行的情况。

2. Messenger的构造方法

3. Messenger 使用

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 {@Overridepublic 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) {}}}}@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}@Overridepublic 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 ponentName;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 {@Overridepublic 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() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {//获取服务端关联的Messenger对象mService = new Messenger(iBinder);Log.e(TAG,"onServiceConnected");}@Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.e(TAG,"onServiceDisconnected");mService=null;}};@Overrideprotected 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() {@Overridepublic 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);}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(conn);mHandler.removeCallbacksAndMessages(null);}}

4. 运行结果

client端的log:

E/MessengerClient: mService.sendE/MessengerClient: mService.sendhandleMessagehandleMessage:510E/MessengerClient: handleMessagehandleMessage:510

Server端的log:

E/MessengerService: handleMessageE/MessengerService: handleMessageE/MessengerService: handleMessageE/MessengerService: handleMessageE/MessengerService: handleMessage

5.原理

先看下 Messenger 的源码,代码行数非常少:

/9.0.0_r3/xref/frameworks/base/core/java/android/os/Messenger.java

/** Copyright (C) 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**/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文件:

/9.0.0_r3/xref/frameworks/base/core/java/android/os/IMessenger.aidl

/* //device/java/android/android/app/IActivityPendingResult.aidl**** Copyright , 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 ****/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,使用起来更简单。

最后,附上文中的示例代码:/download/zzw0221/11260381

参考:

/hzw/article/details/81090319

/p/48e212d1fde4

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。