当前位置:   article > 正文

通过PackageManagerService理解AIDL中的Binder应用_ipackagemanager.stub.asinterface

ipackagemanager.stub.asinterface

目录

一、什么是AIDL

二、PackageManagerService中的AIDL

1、客户端PackageManager的初始化

2、服务端PackageManagerService的初始化

3、客户端PackageManager和服务端PackageManagerService的交互

三、AIDL的Binder使用分析

四、总结


一、什么是AIDL

Google官方文档的定义:

AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似。 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。

简单理解下就是:

AIDL其实就是通过Binder实现的,并且只用开发者定义好aidl文件后,Android 编译系统就会帮我们自动生成用于binder通信的一大堆文件。

如果还不了解Binder可以参考之前的文章:Android Binder 进程间通讯机制

因此它的作用就是:

方便系统为我们生成代码从而实现跨进程通讯,也就是说这个AIDL就只是一个封装了Binder的快速跨进程通讯的工具

二、PackageManagerService中的AIDL

如果之前有看:通过MediaPlayer简单理解Binder的使用

就会发现MediaPlayer的binder通信都是通过c++代码实现的 ,不方便java开发者学习。

并且Android 系统中的大量进程间通信实际上都是通过aidl的方式进行的。因此在学习PackageManagerService之前。我们有必要先学习下aidl是怎么进行进程间通信的

 

 

    

1、客户端PackageManager的初始化

frameworks/base/core/java/android/content/pm/PackageManager.java

  1. 69  public abstract class PackageManager {
  2. 70      private static final String TAG = "PackageManager";
  3. 71  
  4. 72      /** {@hide} */
  5. 73      public static final boolean APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE = true;
  6. 74  
  7. 75      /**
  8. 76       * This exception is thrown when a given package, application, or component
  9. 77       * name cannot be found.
  10. 78       */
  11. 79      public static class NameNotFoundException extends AndroidException {
  12. 80          public NameNotFoundException() {
  13. 81          }
  14. 82  
  15. 83          public NameNotFoundException(String name) {
  16. 84              super(name);
  17. 85          }
  18. 86      }
  19.           ...
  20. 5879  }

 

原来PackageManager就是个普通的接口类,也没有实现其他接口,或者继承其他类。具体的实现ApplicationPackageManager

frameworks/base/core/java/android/app/ApplicationPackageManager.java

  1. 99  public class ApplicationPackageManager extends PackageManager {
  2. 100      private static final String TAG = "ApplicationPackageManager";
  3. 101      private final static boolean DEBUG_ICONS = false;
  4. 102  
  5. 103      private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384// 16KB
  6. 104  
  7. 105      // Default flags to use with PackageManager when no flags are given.
  8. 106      private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
  9.          ...
  10. 1349      ApplicationPackageManager(ContextImpl context,
  11. 1350                                IPackageManager pm) {
  12. 1351          mContext = context;
  13. 1352          mPM = pm;
  14. 1353      }
  15.           ...
  16. 2484  }

可以看到这个ApplicationPackageManager 也仅仅是一个普通的java类。但是他的构造方法的第二个参数却是IPackageManager

并且把它当成服务端再用。那现在就看下这个ApplicationPackageManager是在哪初始化的,并且传入的参数IPackageManager又是从哪来的

frameworks/base/core/java/android/app/ContextImpl.java

  1. 211      public PackageManager getPackageManager() {
  2. 212          if (mPackageManager != null) {
  3. 213              return mPackageManager;
  4. 214          }
  5. 215  
  6. 216          IPackageManager pm = ActivityThread.getPackageManager();
  7. 217          if (pm != null) {
  8. 218              // Doesn't matter if we make more than one instance.
  9. 219              return (mPackageManager = new ApplicationPackageManager(this, pm));
  10. 220          }
  11. 221  
  12. 222          return null;
  13. 223      }

看到他的参数IPackageManager是从 ActivityThread.getPackageManager()获取的 

frameworks/base/core/java/android/app/ActivityThread.java 

  1. 1838      public static IPackageManager getPackageManager() {
  2. 1839          if (sPackageManager != null) {
  3. 1840              //Slog.v("PackageManager""returning cur default = " + sPackageManager);
  4. 1841              return sPackageManager;
  5. 1842          }
  6. 1843          IBinder b = ServiceManager.getService("package");
  7. 1844          //Slog.v("PackageManager""default service binder = " + b);
  8. 1845          sPackageManager = IPackageManager.Stub.asInterface(b);
  9. 1846          //Slog.v("PackageManager""default service = " + sPackageManager);
  10. 1847          return sPackageManager;
  11. 1848      }

可以看到通过ServiceManager.getService("package") 获取指定的IBinder 

然后通过IPackageManager.Stub.asInterface(b) 将IBinder 转化为IPackageManager 

这样就完成了客户端的分析:

客户端再初始化的时候会通过ServiceManager获取服务端的代理

将服务端的代理IPackageManager传入客户端构造,并在客户端使用

2、服务端PackageManagerService的初始化

看下服务端PackManagerService的初始化

frameworks/base/services/java/com/android/server/SystemServer.java

  1. 466          traceBeginAndSlog("StartPackageManagerService");
  2. 467          mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
  3. 468                  mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  4. 469          mFirstBoot = mPackageManagerService.isFirstBoot();
  5. 470          mPackageManager = mSystemContext.getPackageManager();
  6. 471          Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

在SystemServer中调用PackageManagerService.main()方法初始化,看下main方法里都干了什么?

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java 

  1. 2008      public static PackageManagerService main(Context context, Installer installer,
  2. 2009              boolean factoryTest, boolean onlyCore) {
  3. 2010          // Self-check for initial settings.
  4. 2011          PackageManagerServiceCompilerMapping.checkProperties();
  5. 2012  
  6. 2013          PackageManagerService m = new PackageManagerService(context, installer,
  7. 2014                  factoryTest, onlyCore);
  8. 2015          m.enableSystemUserPackages();
  9. 2016          ServiceManager.addService("package", m);
  10. 2017          return m;
  11. 2018      }

可以看到main方法里创建了PackageManagerService 服务并添加到ServiceManager中

 

然后看下PackageManagerService的定义

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

  1. 355  public class PackageManagerService extends IPackageManager.Stub {
  2. 356      static final String TAG = "PackageManager";
  3. 357      static final boolean DEBUG_SETTINGS = false;
  4. 358      static final boolean DEBUG_PREFERRED = false;
  5. 359      static final boolean DEBUG_UPGRADE = false;
  6.          ...
  7. 21445  }

可以看到原来PackageManagerService 就是继承了IPackageManager的内部类Stub,看下IPackageManager

frameworks/base/core/java/android/content/pm/IPackageManager.aidl

  1. 62  interface IPackageManager {
  2. 63      void checkPackageStartable(String packageName, int userId);
  3. 64      boolean isPackageAvailable(String packageName, int userId);
  4. 65      PackageInfo getPackageInfo(String packageName, int flags, int userId);
  5. 66      int getPackageUid(String packageName, int flags, int userId);
  6. 67      int[] getPackageGids(String packageName, int flags, int userId);
  7.           ...
  8. 579  }

 

可以看到aidl实际就是一个类似于java中的接口类,然后定义了一下基本的接口方法,并没有看到内部类Stub啊

原来这就是aidl的便捷所在,只需要定义好aidl文件,编译的时候系统就会自动生成IPackageManager.java文件

让我们看下自动生成的IPackageManager.java文件

3、客户端PackageManager和服务端PackageManagerService的交互

 

out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java

  1. public interface IPackageManager extends android.os.IInterface
  2. {
  3. /** Local-side IPC implementation stub class*/
  4. public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager
  5. {
  6. private static final java.lang.String DESCRIPTOR = "android.content.pm.IPackageManager";
  7. /** Construct the stub at attach it to the interface*/
  8. public Stub()
  9. {
  10. this.attachInterface(this, DESCRIPTOR);
  11. }
  12. /**
  13.  * Cast an IBinder object into an android.content.pm.IPackageManager interface,
  14.  * generating a proxy if needed.
  15.  */
  16. public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj)
  17. {
  18. if ((obj==null)) {
  19. return null;
  20. }
  21. android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
  22. if (((iin!=null)&&(iin instanceof android.content.pm.IPackageManager))) {
  23. return ((android.content.pm.IPackageManager)iin);
  24. }
  25. return new android.content.pm.IPackageManager.Stub.Proxy(obj);
  26. }
  27. @Override public android.os.IBinder asBinder()
  28. {
  29. return this;
  30. }
  31. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
  32. {
  33. switch (code)
  34. {
  35. case INTERFACE_TRANSACTION:
  36. {
  37. reply.writeString(DESCRIPTOR);
  38. return true;
  39. }
  40. private static class Proxy implements android.content.pm.IPackageManager
  41. {
  42. private android.os.IBinder mRemote;
  43. Proxy(android.os.IBinder remote)
  44. {
  45. mRemote = remote;
  46. }
  47. @Override public android.os.IBinder asBinder()
  48. {
  49. return mRemote;
  50. }
  51. public java.lang.String getInterfaceDescriptor()
  52. {
  53. return DESCRIPTOR;
  54. }

 

IPackageManager接口类中定义了服务端和客户端通信的业务函数,还定义了内部类Stub,该类从Binder派生并实现了IPackageManager接口。

PackageManagerService继承自IPackageManager.Stub类,由于Stub类从Binder派生,因此PackageManagerService将作为服务端参与Binder通信。

Stub类中定义了一个内部类Proxy,该类有一个IBinder类型(实际类型为BinderProxy)的成员变量mRemote,根据第2章介绍的Binder系统的知识,mRemote用于和服务端PackageManagerService通信。

IPackageManager接口类中定义了许多业务函数,但是出于安全等方面的考虑,Android对外(即SDK)提供的只是一个子集,该子集被封装在抽象类PackageManager中。客户端一般通过Context的getPackageManager函数返回一个类型为PackageManager的对象,该对象的实际类型PackageManager的子类ApplicationPackageManager。这种基于接口编程的方式,虽然极大降低了模块之间的耦合性,却给代码分析带来了不小的麻烦。

ApplicationPackageManager类继承自PackageManager类。它并没有直接参与Binder通信,而是通过mPM成员变量指向一个IPackageManager.Stub.Proxy类型的对象。

 

三、AIDL的Binder使用分析

 

剩下的步骤

1、asInterface将参数IBinder 转化为IPackageManager 可以参考通过MediaPlayer简单理解Binder的使用 中的IBinder转化为IMediaPlayerService的内容

2、onTransact方法的回调 也可以参考通过MediaPlayer简单理解Binder的使用 中的对应部分

  1. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
  2. {
  3. switch (code)
  4. {
  5. case INTERFACE_TRANSACTION:
  6. {
  7. reply.writeString(DESCRIPTOR);
  8. return true;
  9. }
  10. case TRANSACTION_checkPackageStartable:
  11. {
  12. data.enforceInterface(DESCRIPTOR);
  13. java.lang.String _arg0;
  14. _arg0 = data.readString();
  15. int _arg1;
  16. _arg1 = data.readInt();
  17. this.checkPackageStartable(_arg0, _arg1);
  18. reply.writeNoException();
  19. return true;
  20. }
  21. case TRANSACTION_isPackageAvailable:
  22. {
  23. data.enforceInterface(DESCRIPTOR);
  24. java.lang.String _arg0;
  25. _arg0 = data.readString();
  26. int _arg1;
  27. _arg1 = data.readInt();
  28. boolean _result = this.isPackageAvailable(_arg0, _arg1);
  29. reply.writeNoException();
  30. reply.writeInt(((_result)?(1):(0)));
  31. return true;
  32. }
  33. case TRANSACTION_getPackageInfo:
  34. {
  35. data.enforceInterface(DESCRIPTOR);
  36. java.lang.String _arg0;

onTransact 方法中的具体实现就是调用this.xxx,而这个this正事继承了IPackageManager.Sutb 的 PackageManagerService

四、总结

1、服务端PackageManagerService 开机初始化后将自己添加到ServiceManager.addService()

2、客户端ApplicationPackageManager 通过ServiceManager.getService()找到服务端的代理IPackageManager

3、创建客户端的时候通过客户端构造方法将IPackageManager传入,并使用

4、IPackageManager代理最终会通过onTransact方法中的this.xxx 调用继承了IPackageManager的服务端PackageManagerService执行具体的方法

至此,ApplicationPackageManager 和PackageManagerService的通信到此结束。后续分析时就可以知道直接跳过两个进程通信的部分,直接看相应业务代码了。

接下来想了解PackageManagerService可以参考:PackageManagerService服务框架分析

注:图片来源网络,侵删!

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

闽ICP备14008679号