简单分析 mPM.getPackageInfo() 调用流程

来源:互联网 发布:淘宝手机端卖家中心 编辑:程序博客网 时间:2024/06/08 15:08

上文分析了 mContext.getPackageManager() 调用流程,本文再简单说下 mPM.getPacakgeInfo()调用流程。

这里就涉及到了 binder 知识。

mPM 是 ApplicationPackageManager.java 类型,此类封装了 IPackageManager 的实现。

    @Override    public PackageInfo getPackageInfo(String packageName, int flags)            throws NameNotFoundException {        return getPackageInfoAsUser(packageName, flags, mContext.getUserId());    }    @Override    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)            throws NameNotFoundException {        try {            PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId);            if (pi != null) {                return pi;            }        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }        throw new NameNotFoundException(packageName);    }

这里我们就要分析 IPacakgeManager.java,这个java文件是编译时转好 AIDL 文件生成的,这个AIDL文件位置:

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

/**
 *  See {@link PackageManager} for documentation on most of the APIs
 *  here.
 *
 *  {@hide}
 */
interface IPackageManager {
    void checkPackageStartable(String packageName, int userId);
    boolean isPackageAvailable(String packageName, int userId);
    PackageInfo getPackageInfo(String packageName, int flags, int userId);

.........................

说白了,aidl 文件顾名思义就是定义接口描述:接口名称,接口参数,返回值类型。跨进程通讯双方遵循这个格式传递数据。

Android在编译代码的时候转化未 IPackageManager.java文件:

@Override public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();android.content.pm.PackageInfo _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(packageName);_data.writeInt(flags);_data.writeInt(userId);mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);_reply.readException();if ((0!=_reply.readInt())) {_result = android.content.pm.PackageInfo.CREATOR.createFromParcel(_reply);}else {_result = null;}}finally {_reply.recycle();_data.recycle();}return _result;}
从上面自动生成的代码可以看出,getPackageInfo 函数讲传入参数打包成 Parcel请求,作为一个业务调用 mRemote.transact 函数发送到系统进程。

这个 mRemote 是个代理类,在 IPacakgeManager.java 实例化时就被创建:

/** * 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);}
..........
private static class Proxy implements android.content.pm.IPackageManager{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}
.............
这个 transact 函数是在 frameworks/base/core/java/android/os/Binder.java 中由 BinderProxy 类实现的:

final class BinderProxy implements IBinder {    public native boolean pingBinder();    public native boolean isBinderAlive();    public IInterface queryLocalInterface(String descriptor) {        return null;    }    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");        if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }        return transactNative(code, data, reply, flags);    }
从前面 IPackageManager 从 ActivityThread.java 中获取到的,这个从 ServiceManager 获取的 IBinder 接口来自于 PackageManagerService.java

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

public class PackageManagerService extends IPackageManager.Stub {
....
     public static PackageManagerService main(Context context, Installer installer,            boolean factoryTest, boolean onlyCore) {        // Self-check for initial settings.        PackageManagerServiceCompilerMapping.checkProperties();        PackageManagerService m = new PackageManagerService(context, installer,                factoryTest, onlyCore);        m.enableSystemUserPackages();        ServiceManager.addService("package", m);        return m;    }

IPackageManager.java我们可以看到 IPackageManager.Stub继承自 android.os.Binder。

所以那个 transact 函数最终掉一个到 Binder.java 里的实现,最终走到 c 语言 so 库里执行。











阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宛然拼音 谢宛然苏响陆屿全文免费阅读 宛然的意思是什么 宛瑜 宛瑜扮演者 宛瑜借给大哥 吕子乔干一菲 宛瑜 宛萍 宛转的拼音 宛转悠扬 宛香 宛香 佟佳东珠 宜丰 宜丰县 宜丰信息港 宜丰在线 江西宜丰 宜丰就业网 宜丰蛋糕 宜丰鲜花 宜丰信息网 宜丰租房 宜丰租房子 宜丰在线网 宜丰吧 宜丰人才网 宜丰招聘 江西宜丰县 宜丰县属于哪个市 宜丰县公共资源交易网 宜丰哪里好玩 宜丰有大润发超市嗎 宜丰汽车站电话号码 宜丰在线招聘信息网 宜丰房产信息网 秋色宜人 宜人贷利息 景色宜人 宜人贷征信 宜人普惠 宜人贷股价