Android插件化探索(三)免安装运行Activity(上)

转载请注明本文出自maplejaw的博客http://blog.csdn.net/maplejaw_

【Android插件化探索(一)类加载器DexClassLoader】
【Android插件化探索(二)资源加载】

前情提要

在上一篇中有一个细节没有提到,那就是getResourcesForApplication和AssetManager的区别。

getResourcesForApplication

getResourcesForApplication(String packageName),很显然需要传入一个包名,换言之,这个插件必须已经被安装在系统内,然后才能通过包名来获取资源。你可能会想,不安装照样可以获取包名啊。的确,通过pm.getPackageArchiveInfo()可以获取安装包信息。但是,这些包都是没有在PMS中注册的。如果仍然这样获取,会提示如下错误。

android.content.pm.PackageManager$NameNotFoundException: com.maplejaw.hotplugin

现在我们就从源码角度来分析getResourcesForApplication。源码在ApplicationPackageManager中,如下:

    @Override
    public Resources getResourcesForApplication(String appPackageName)
            throws NameNotFoundException {
        return getResourcesForApplication(
            getApplicationInfo(appPackageName, sDefaultFlags));
    }

可以看出内部调用了重载方法。getApplicationInfo返回的是ApplicationInfo对象。

    @Override
    public Resources getResourcesForApplication(@NonNull ApplicationInfo app){

        //...
        //省略了部分源码
        final Resources r = mContext.mMainThread.getTopLevelResources(
                sameUid ? app.sourceDir : app.publicSourceDir,
                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
                app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
                null, mContext.mPackageInfo);
        if (r != null) {
            return r;
        }

    }

最终走的仍旧是ActivityThread的getTopLevelResources,ActivityThread里面的相关源码我就不分析了,跟上一篇是一样的也是调用ResourcesManager中的getTopLevelResources,这里不做赘述。

现在我们主要来看看getApplicationInfo里面做了什么?

  @Override
public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException {
      ApplicationInfo ai =   mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
        //...
        //省略了部分源码
        throw new NameNotFoundException(packageName);
    }

mPM的初始化源码如下,可以看出是一个PMS(PackageManagerService)对象。

    public static IPackageManager getPackageManager() {
        if (sPackageManager != null) {
            return sPackageManager;
        }
        IBinder b = ServiceManager.getService("package");
        sPackageManager = IPackageManager.Stub.asInterface(b);
        return sPackageManager;
    }

继续深究,找出PMS中相关源码。

@Override
    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
        if (!sUserManager.exists(userId)) return 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值