当前位置:   article > 正文

Android 进程间通信:Messenger_android messenger appkey appsercret

android messenger appkey appsercret

1.概述

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

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

2. Messenger的构造方法

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 getBinder().

3. Messenger 使用 

3.1 客户端步骤:

3.1.1 创建一个handler对象,并实现 handleMessage() 方法,用户接收客户端的消息。

3.1.2 创建Messenger ,封装handler。

3.1.3 用Messenger的 getBinder() 方法获取一个IBinder对象,通过 onBind 返回给客户端。

服务端的Service:

  1. package cn.zzw.messenger.server;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Handler;
  5. import android.os.IBinder;
  6. import android.os.Message;
  7. import android.os.Messenger;
  8. import android.os.RemoteException;
  9. import android.util.Log;
  10. public class MessengerService extends Service {
  11. private static final String TAG = "MessengerService";
  12. private MessengerHandler mHandler = new MessengerHandler();
  13. private Messenger mMessenger = new Messenger(mHandler);
  14. private static final int MSG_SUM = 10086;
  15. private class MessengerHandler extends Handler {
  16. @Override
  17. public void handleMessage(Message msg) {
  18. if(msg.what==MSG_SUM)
  19. {
  20. Log.e(TAG,"handleMessage");
  21. try {
  22. int arg1 = msg.arg1;
  23. int arg2=msg.arg2;
  24. Message msgToClient=Message.obtain(msg);
  25. msgToClient.arg1=arg1+arg2;
  26. msg.replyTo.send(msgToClient);
  27. } catch (RemoteException e) {
  28. }
  29. }
  30. }
  31. }
  32. @Override
  33. public IBinder onBind(Intent intent) {
  34. return mMessenger.getBinder();
  35. }
  36. @Override
  37. public void onDestroy() {
  38. super.onDestroy();
  39. mHandler.removeCallbacksAndMessages(null);
  40. }
  41. }

3.2 客户端步骤:

3.2.1 在 Activity 中绑定服务。

3.2.2 创建ServiceConnection并在其中使用 IBinder 将 Messenger实例化

3.2.3 使用Messenger向服务端发送消息

客户端主要代码:

  1. package cn.zzw.messenger.client;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.content.ComponentName;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.IBinder;
  9. import android.os.Message;
  10. import android.os.Messenger;
  11. import android.os.RemoteException;
  12. import android.util.Log;
  13. import android.view.View;
  14. import android.widget.Button;
  15. import android.widget.TextView;
  16. import android.widget.Toast;
  17. public class MainActivity extends AppCompatActivity {
  18. private static final String TAG = "MessengerClient";
  19. private TextView mTv;
  20. private Messenger mService;
  21. private static final int MSG_SUM = 10086;
  22. private MessengerHandler mHandler = new MessengerHandler();
  23. private Messenger mMessenger = new Messenger(mHandler);
  24. private class MessengerHandler extends Handler {
  25. @Override
  26. public void handleMessage(Message msg) {
  27. if(msg.what==MSG_SUM)
  28. {
  29. Log.e(TAG,"handleMessage");
  30. int arg1 = msg.arg1;
  31. Log.e(TAG,"handleMessage:"+arg1);
  32. Toast.makeText(MainActivity.this,"The Result is "+arg1,Toast.LENGTH_SHORT).show();
  33. }
  34. }
  35. }
  36. private ServiceConnection conn=new ServiceConnection() {
  37. @Override
  38. public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
  39. //获取服务端关联的Messenger对象
  40. mService = new Messenger(iBinder);
  41. Log.e(TAG,"onServiceConnected");
  42. }
  43. @Override
  44. public void onServiceDisconnected(ComponentName componentName) {
  45. Log.e(TAG,"onServiceDisconnected");
  46. mService=null;
  47. }
  48. };
  49. @Override
  50. protected void onCreate(Bundle savedInstanceState) {
  51. super.onCreate(savedInstanceState);
  52. setContentView(R.layout.activity_main);
  53. bindToServserService();
  54. mTv = findViewById(R.id.mTv);
  55. findViewById(R.id.mBtn_cal).setOnClickListener(new View.OnClickListener() {
  56. @Override
  57. public void onClick(View view) {
  58. Message msg = Message.obtain(null, MSG_SUM, 10, 500);
  59. msg.replyTo = mMessenger;
  60. if(null!=mService)
  61. {
  62. //往服务端发送消息
  63. try {
  64. Log.e(TAG,"mService.send");
  65. mService.send(msg);
  66. } catch (RemoteException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. }
  71. });
  72. }
  73. /*
  74. * 绑定服务端的Service
  75. */
  76. private void bindToServserService() {
  77. Intent intent=new Intent();
  78. intent.setPackage("cn.zzw.messenger.server");
  79. intent.setAction("CN.ZZW.MESSENGER.SERVER");
  80. bindService(intent,conn,BIND_AUTO_CREATE);
  81. }
  82. @Override
  83. protected void onDestroy() {
  84. super.onDestroy();
  85. unbindService(conn);
  86. mHandler.removeCallbacksAndMessages(null);
  87. }
  88. }

4. 运行结果

client端的log:

  1. E/MessengerClient: mService.send
  2. E/MessengerClient: mService.send
  3. handleMessage
  4. handleMessage:510
  5. E/MessengerClient: handleMessage
  6. handleMessage:510

Server端的log:

  1. E/MessengerService: handleMessage
  2. E/MessengerService: handleMessage
  3. E/MessengerService: handleMessage
  4. E/MessengerService: handleMessage
  5. E/MessengerService: handleMessage

 

5.原理

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

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/Messenger.java

  1. /*
  2. * Copyright (C) 2006 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package android.os;
  17. /**
  18. * Reference to a Handler, which others can use to send messages to it.
  19. * This allows for the implementation of message-based communication across
  20. * processes, by creating a Messenger pointing to a Handler in one process,
  21. * and handing that Messenger to another process.
  22. *
  23. * <p>Note: the implementation underneath is just a simple wrapper around
  24. * a {@link Binder} that is used to perform the communication. This means
  25. * semantically you should treat it as such: this class does not impact process
  26. * lifecycle management (you must be using some higher-level component to tell
  27. * the system that your process needs to continue running), the connection will
  28. * break if your process goes away for any reason, etc.</p>
  29. */
  30. public final class Messenger implements Parcelable {
  31. private final IMessenger mTarget;
  32. /**
  33. * Create a new Messenger pointing to the given Handler. Any Message
  34. * objects sent through this Messenger will appear in the Handler as if
  35. * {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
  36. * been called directly.
  37. *
  38. * @param target The Handler that will receive sent messages.
  39. */
  40. public Messenger(Handler target) {
  41. mTarget = target.getIMessenger();
  42. }
  43. /**
  44. * Send a Message to this Messenger's Handler.
  45. *
  46. * @param message The Message to send. Usually retrieved through
  47. * {@link Message#obtain() Message.obtain()}.
  48. *
  49. * @throws RemoteException Throws DeadObjectException if the target
  50. * Handler no longer exists.
  51. */
  52. public void send(Message message) throws RemoteException {
  53. mTarget.send(message);
  54. }
  55. /**
  56. * Retrieve the IBinder that this Messenger is using to communicate with
  57. * its associated Handler.
  58. *
  59. * @return Returns the IBinder backing this Messenger.
  60. */
  61. public IBinder getBinder() {
  62. return mTarget.asBinder();
  63. }
  64. /**
  65. * Comparison operator on two Messenger objects, such that true
  66. * is returned then they both point to the same Handler.
  67. */
  68. public boolean equals(Object otherObj) {
  69. if (otherObj == null) {
  70. return false;
  71. }
  72. try {
  73. return mTarget.asBinder().equals(((Messenger)otherObj)
  74. .mTarget.asBinder());
  75. } catch (ClassCastException e) {
  76. }
  77. return false;
  78. }
  79. public int hashCode() {
  80. return mTarget.asBinder().hashCode();
  81. }
  82. public int describeContents() {
  83. return 0;
  84. }
  85. public void writeToParcel(Parcel out, int flags) {
  86. out.writeStrongBinder(mTarget.asBinder());
  87. }
  88. public static final Parcelable.Creator<Messenger> CREATOR
  89. = new Parcelable.Creator<Messenger>() {
  90. public Messenger createFromParcel(Parcel in) {
  91. IBinder target = in.readStrongBinder();
  92. return target != null ? new Messenger(target) : null;
  93. }
  94. public Messenger[] newArray(int size) {
  95. return new Messenger[size];
  96. }
  97. };
  98. /**
  99. * Convenience function for writing either a Messenger or null pointer to
  100. * a Parcel. You must use this with {@link #readMessengerOrNullFromParcel}
  101. * for later reading it.
  102. *
  103. * @param messenger The Messenger to write, or null.
  104. * @param out Where to write the Messenger.
  105. */
  106. public static void writeMessengerOrNullToParcel(Messenger messenger,
  107. Parcel out) {
  108. out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
  109. : null);
  110. }
  111. /**
  112. * Convenience function for reading either a Messenger or null pointer from
  113. * a Parcel. You must have previously written the Messenger with
  114. * {@link #writeMessengerOrNullToParcel}.
  115. *
  116. * @param in The Parcel containing the written Messenger.
  117. *
  118. * @return Returns the Messenger read from the Parcel, or null if null had
  119. * been written.
  120. */
  121. public static Messenger readMessengerOrNullFromParcel(Parcel in) {
  122. IBinder b = in.readStrongBinder();
  123. return b != null ? new Messenger(b) : null;
  124. }
  125. /**
  126. * Create a Messenger from a raw IBinder, which had previously been
  127. * retrieved with {@link #getBinder}.
  128. *
  129. * @param target The IBinder this Messenger should communicate with.
  130. */
  131. public Messenger(IBinder target) {
  132. mTarget = IMessenger.Stub.asInterface(target);
  133. }
  134. }

这时候我们在回头看两个构造方法:

  1. 1. public Messenger(Handler target) {
  2. mTarget = target.getIMessenger();
  3. }
  4. 2. public Messenger(IBinder target) {
  5. mTarget = IMessenger.Stub.asInterface(target);
  6. }

 两个构造方法内部都是初始化对象 mTarget:

private final IMessenger mTarget;

再看看 IMessenger,是一个AIDL文件:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/IMessenger.aidl

  1. /* //device/java/android/android/app/IActivityPendingResult.aidl
  2. **
  3. ** Copyright 2007, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. ** http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */
  17. package android.os;
  18. import android.os.Message;
  19. /** @hide */
  20. oneway interface IMessenger {
  21. void send(in Message msg);
  22. }

在看看Handler 中的部分代码:

  1. final IMessenger getIMessenger() {
  2. synchronized (mQueue) {
  3. if (mMessenger != null) {
  4. return mMessenger;
  5. }
  6. mMessenger = new MessengerImpl();
  7. return mMessenger;
  8. }
  9. }
  10. private final class MessengerImpl extends IMessenger.Stub {
  11. public void send(Message msg) {
  12. msg.sendingUid = Binder.getCallingUid();
  13. Handler.this.sendMessage(msg);
  14. }
  15. }

从以上代码,可以看出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

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/122563?site
推荐阅读
相关标签
  

闽ICP备14008679号