Android动态资源加载原理和应用

动态加载资源原理

通常我们调用getResources()方法获取资源文件

public Resources getResources() {
    return mResources;
}
mResources是在创建ContextImp对象后的init方法里面创建的

mResources = mPackageInfo.getResources(mainThread);
调用了LoadedApk的getResources方法
public Resources getResources(ActivityThread mainThread) {
    if (mResources == null) {
        mResources = mainThread.getTopLevelResources(mResDir,
                Display.DEFAULT_DISPLAY, null, this);
    }
    return mResources;
}
又调用到了ActivityThread类的getTopLevelResources方法

Resources getTopLevelResources(String resDir, int displayId, Configuration overrideConfiguration, CompatibilityInfo compInfo) {
    ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, compInfo.applicationScale, compInfo.isThemeable);
    Resources r;
    synchronized (mPackages) {
        // ...
        WeakReference<Resources> wr = mActiveResources.get(key);
        r = wr != null ? wr.get() : null;
        if (r != null && r.getAssets().isUpToDate()) {
            if (false) {
                Slog.w(TAG, "Returning cached resources " + r + " " + resDir
                        + ": appScale=" + r.getCompatibilityInfo().applicationScale);
            }
            return r;
        }
    }
    
    AssetManager assets = new AssetManager();
    assets.setThemeSupport(compInfo.isThemeable);
    if (assets.addAssetPath(resDir) == 0) {
        return null;
    }

    // ...

    r = new Resources(assets, dm, config, compInfo);
    if (false) {
        Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
                + r.getConfiguration() + " appScale="
                + r.getCompatibilityInfo().applicationScale);
    }

    synchronized (mPackages) {
        WeakReference<Resources> wr = mActiveResources.get(key);
        Resources existing = wr != null ? wr.get() : null;
        if (existing != null && existing.getAssets().isUpToDate()) {
            // Someone else already created the resources while we were
            // unlocked; go ahead and use theirs.
            r.getAssets().close();
            return existing;
        }
        
        // XXX need to remove entries when weak references go away
        mActiveResources.put(key, new WeakReference<Resources>(r));
        return r;
    }
}
ResourcesKey使用resDir和其他参数来构造,这里主要是resDir参数,表明资源文件所在的路径。也就是APK程序所在路径。

ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, compInfo.applicationScale, compInfo.isThemeable);
上面代码的主要逻辑是获取Resources对象,从一个Map变量mActiveResources获取,这个Map维护了ResourcesKey和WeakReference<Resources>的对应关系。如果不存在就创建它,并且添加到Map中。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值