赞
踩
目录
2、服务端PackageManagerService的初始化
3、客户端PackageManager和服务端PackageManagerService的交互
Google官方文档的定义:
AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似。 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。
简单理解下就是:
AIDL其实就是通过Binder实现的,并且只用开发者定义好aidl文件后,Android 编译系统就会帮我们自动生成用于binder通信的一大堆文件。
如果还不了解Binder可以参考之前的文章:Android Binder 进程间通讯机制
因此它的作用就是:
方便系统为我们生成代码从而实现跨进程通讯,也就是说这个AIDL就只是一个封装了Binder的快速跨进程通讯的工具
如果之前有看:通过MediaPlayer简单理解Binder的使用
就会发现MediaPlayer的binder通信都是通过c++代码实现的 ,不方便java开发者学习。
并且Android 系统中的大量进程间通信实际上都是通过aidl的方式进行的。因此在学习PackageManagerService之前。我们有必要先学习下aidl是怎么进行进程间通信的
frameworks/base/core/java/android/content/pm/PackageManager.java
- 69 public abstract class PackageManager {
- 70 private static final String TAG = "PackageManager";
- 71
- 72 /** {@hide} */
- 73 public static final boolean APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE = true;
- 74
- 75 /**
- 76 * This exception is thrown when a given package, application, or component
- 77 * name cannot be found.
- 78 */
- 79 public static class NameNotFoundException extends AndroidException {
- 80 public NameNotFoundException() {
- 81 }
- 82
- 83 public NameNotFoundException(String name) {
- 84 super(name);
- 85 }
- 86 }
- ...
- 5879 }
原来PackageManager就是个普通的接口类,也没有实现其他接口,或者继承其他类。具体的实现ApplicationPackageManager
frameworks/base/core/java/android/app/ApplicationPackageManager.java
- 99 public class ApplicationPackageManager extends PackageManager {
- 100 private static final String TAG = "ApplicationPackageManager";
- 101 private final static boolean DEBUG_ICONS = false;
- 102
- 103 private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
- 104
- 105 // Default flags to use with PackageManager when no flags are given.
- 106 private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
- ...
- 1349 ApplicationPackageManager(ContextImpl context,
- 1350 IPackageManager pm) {
- 1351 mContext = context;
- 1352 mPM = pm;
- 1353 }
- ...
- 2484 }
可以看到这个ApplicationPackageManager 也仅仅是一个普通的java类。但是他的构造方法的第二个参数却是IPackageManager
并且把它当成服务端再用。那现在就看下这个ApplicationPackageManager是在哪初始化的,并且传入的参数IPackageManager又是从哪来的
frameworks/base/core/java/android/app/ContextImpl.java
- 211 public PackageManager getPackageManager() {
- 212 if (mPackageManager != null) {
- 213 return mPackageManager;
- 214 }
- 215
- 216 IPackageManager pm = ActivityThread.getPackageManager();
- 217 if (pm != null) {
- 218 // Doesn't matter if we make more than one instance.
- 219 return (mPackageManager = new ApplicationPackageManager(this, pm));
- 220 }
- 221
- 222 return null;
- 223 }
看到他的参数IPackageManager是从 ActivityThread.getPackageManager()获取的
frameworks/base/core/java/android/app/ActivityThread.java
- 1838 public static IPackageManager getPackageManager() {
- 1839 if (sPackageManager != null) {
- 1840 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
- 1841 return sPackageManager;
- 1842 }
- 1843 IBinder b = ServiceManager.getService("package");
- 1844 //Slog.v("PackageManager", "default service binder = " + b);
- 1845 sPackageManager = IPackageManager.Stub.asInterface(b);
- 1846 //Slog.v("PackageManager", "default service = " + sPackageManager);
- 1847 return sPackageManager;
- 1848 }
可以看到通过ServiceManager.getService("package") 获取指定的IBinder
然后通过IPackageManager.Stub.asInterface(b) 将IBinder 转化为IPackageManager
这样就完成了客户端的分析:
客户端再初始化的时候会通过ServiceManager获取服务端的代理
将服务端的代理IPackageManager传入客户端构造,并在客户端使用
看下服务端PackManagerService的初始化
frameworks/base/services/java/com/android/server/SystemServer.java
- 466 traceBeginAndSlog("StartPackageManagerService");
- 467 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
- 468 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
- 469 mFirstBoot = mPackageManagerService.isFirstBoot();
- 470 mPackageManager = mSystemContext.getPackageManager();
- 471 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
在SystemServer中调用PackageManagerService.main()方法初始化,看下main方法里都干了什么?
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- 2008 public static PackageManagerService main(Context context, Installer installer,
- 2009 boolean factoryTest, boolean onlyCore) {
- 2010 // Self-check for initial settings.
- 2011 PackageManagerServiceCompilerMapping.checkProperties();
- 2012
- 2013 PackageManagerService m = new PackageManagerService(context, installer,
- 2014 factoryTest, onlyCore);
- 2015 m.enableSystemUserPackages();
- 2016 ServiceManager.addService("package", m);
- 2017 return m;
- 2018 }
可以看到main方法里创建了PackageManagerService 服务并添加到ServiceManager中
然后看下PackageManagerService的定义
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- 355 public class PackageManagerService extends IPackageManager.Stub {
- 356 static final String TAG = "PackageManager";
- 357 static final boolean DEBUG_SETTINGS = false;
- 358 static final boolean DEBUG_PREFERRED = false;
- 359 static final boolean DEBUG_UPGRADE = false;
- ...
- 21445 }
可以看到原来PackageManagerService 就是继承了IPackageManager的内部类Stub,看下IPackageManager
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
- 62 interface IPackageManager {
- 63 void checkPackageStartable(String packageName, int userId);
- 64 boolean isPackageAvailable(String packageName, int userId);
- 65 PackageInfo getPackageInfo(String packageName, int flags, int userId);
- 66 int getPackageUid(String packageName, int flags, int userId);
- 67 int[] getPackageGids(String packageName, int flags, int userId);
- ...
- 579 }
可以看到aidl实际就是一个类似于java中的接口类,然后定义了一下基本的接口方法,并没有看到内部类Stub啊
原来这就是aidl的便捷所在,只需要定义好aidl文件,编译的时候系统就会自动生成IPackageManager.java文件
让我们看下自动生成的IPackageManager.java文件
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java
- public interface IPackageManager extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager
- {
- private static final java.lang.String DESCRIPTOR = "android.content.pm.IPackageManager";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an android.content.pm.IPackageManager interface,
- * generating a proxy if needed.
- */
- public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj)
- {
- if ((obj==null)) {
- return null;
- }
- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (((iin!=null)&&(iin instanceof android.content.pm.IPackageManager))) {
- return ((android.content.pm.IPackageManager)iin);
- }
- return new android.content.pm.IPackageManager.Stub.Proxy(obj);
- }
- @Override public android.os.IBinder asBinder()
- {
- return this;
- }
- @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
- {
- switch (code)
- {
- case INTERFACE_TRANSACTION:
- {
- reply.writeString(DESCRIPTOR);
- return true;
- }
-
-
-
- private static class Proxy implements android.content.pm.IPackageManager
- {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote)
- {
- mRemote = remote;
- }
- @Override public android.os.IBinder asBinder()
- {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor()
- {
- return DESCRIPTOR;
- }
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类型的对象。
剩下的步骤
1、asInterface将参数IBinder 转化为IPackageManager 可以参考通过MediaPlayer简单理解Binder的使用 中的IBinder转化为IMediaPlayerService的内容
2、onTransact方法的回调 也可以参考通过MediaPlayer简单理解Binder的使用 中的对应部分
- @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
- {
- switch (code)
- {
- case INTERFACE_TRANSACTION:
- {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_checkPackageStartable:
- {
- data.enforceInterface(DESCRIPTOR);
- java.lang.String _arg0;
- _arg0 = data.readString();
- int _arg1;
- _arg1 = data.readInt();
- this.checkPackageStartable(_arg0, _arg1);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_isPackageAvailable:
- {
- data.enforceInterface(DESCRIPTOR);
- java.lang.String _arg0;
- _arg0 = data.readString();
- int _arg1;
- _arg1 = data.readInt();
- boolean _result = this.isPackageAvailable(_arg0, _arg1);
- reply.writeNoException();
- reply.writeInt(((_result)?(1):(0)));
- return true;
- }
- case TRANSACTION_getPackageInfo:
- {
- data.enforceInterface(DESCRIPTOR);
- 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服务框架分析
注:图片来源网络,侵删!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。