插件化基础知识之二———成也PackageMnager,败也PackageManager

前言:

引起对PackageManager的思考的是:插件化实现对未安装的apk进行启动,那么,未安装的apk与已安装的apk有什么区别?这些区别又是谁造成的呢?谈及这个问题时,我们不得不面对PM。

内容目录:

(1).PackageManager的作用

(2).PM的本质以及来源

(3).PM的安装流程以及安装本质

(4)备注

1.PackageManager的作用

1.安装和卸载应用

2.获取关于应用的各种信息,比如Application的名称,四大组件的信息。

之所以有这种功能,是在安装app时,首先读取了AndroidManifest中的各个节点信息。

3.获取系统中各种分类应用(比如已安装应用,最近使用的应用等)

4.权限的获取与处理

具体的方法如下:

https://blog.csdn.net/da_caoyuan/article/details/52908797

2.PM的本质以及来源

(1).PackageManager的获取可以从Activity直接获取:

PackageManager packageManager = getPackageManager();

(2)进入后是ContextWrapper的调用,实际上,ContextWrapper只是Context的包装类,而实现类是ContexImpl.

  public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }

        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }

        return null;
    }

(3)PackageManger是ApplicationPackageManager,而ApplicationPackageManager实际上只是一个包装类,用来包装IPackageManager。而IPackageManger是AIDL通信的接口,对应于PackageManagerService。

  //通过这两个方法可以看出,实际上的实现都是mPM
private int installExistingPackageAsUser(String packageName, int installReason, int userId)
            throws NameNotFoundException {
        try {
            int res = mPM.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/,
                    installReason);
            if (res == INSTALL_FAILED_INVALID_URI) {
                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
            }
            return res;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public void verifyPendingInstall(int id, int response) {
        try {
            mPM.verifyPendingInstall(id, response);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

    }

(4)接下来,咱们来看牛13的ActivityThread(它的牛逼,看过应用冷启动流程的同学应该知悉,不知道的同学可以查查资料)。

//ServiceManager是对SystemService进行管理的类,“package”对应于PackageManagerService,关于
ServiceManager可以看下源码
public static IPackageManager getPackageManager() {
        if (sPackageManager != null) {
            //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
            return sPackageManager;
        }
        IBinder b = ServiceManager.getService("package");
        //Slog.v("PackageManager", "default service binder = " + b);
        sPackageManager = IPackageManager.Stub.asInterface(b);
        //Slog.v("PackageManager", "default service = " + sPackageManager);
        return sPackageManager;
    }

(4.1)关于ServiceManager.getService,实际上在系统启动时,启动系统服务,会将AM等各个服务添加到服务管理类中。


/**
     * Returns a reference to a service with the given name.
     *
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn't exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

4.备注

(1).系统源码的在线查看,用的是Android社区源码查看

http://www.androidos.net.cn/

上一篇:动态隐藏App启动图标


下一篇:Android开发分渠道打包之友盟篇