系列帖子:
Android插件化原理(一)—— 插件类加载、类加载原理、(双亲委托机制)
Android插件化原理(二)—启动插件Activity
应用
单作为一个技术点来讲,其实没有什么意义,还是要围绕需求展开的,加载插件资源最常见的应用就是插件化换肤了。我们直到,apk绝大部分体积都是资源,如果多套主题皮肤,那么包体积就会增加很多,
所以插件化换肤就很实用。可以实现多样化主题,个性化定制,提高了应用的灵活性和扩展性。
应用加载资源的原理
要看加载资源的原理,我们先看一下,在实际运行中如何获取资源的
如何获取资源
Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getResources().getDrawable();
getDrawable(0);
}
Context
@Nullable
public final Drawable getDrawable(@DrawableRes int id) {
return getResources().getDrawable(id, getTheme());
}
实际上,不论是直接调用getDrawable或者Resource().getDrawable(),亦或者getContext().getDrawable()最终调用的都是Re
Resources的方法
Resources
public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
throws NotFoundException {
return getDrawableForDensity(id, 0, theme);
}
@Nullable
public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
final TypedValue value = obtainTempTypedValue();
try {
final ResourcesImpl impl = mResourcesImpl;
impl.getValueForDensity(id, density, value, true);
return impl.loadDrawable(this, value, id, density, theme);
} finally {
releaseTempTypedValue(value);
}
}
ResourcesImpl
void getValueForDensity(@AnyRes int id, int density, TypedValue outValue,
boolean resolveRefs) throws NotFoundException {
boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs);
if (found) {
return;
}
throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id));
}
其中,最重要的就是 mAssets.getResourceValue(id, density, outValue, resolveRefs),而mAssets就是android.content.res.AssetManager,
AssetManager
boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
boolean resolveRefs) {
Preconditions.checkNotNull(outValue, "outValue");
synchronized (this) {
ensureValidLocked();
final int cookie = nativeGetResourceValue(
mObject, resId, (short) densityDpi, outValue, resolveRefs);
if (cookie <= 0) {
return false;
}
// Convert the changing configurations flags populated by native code.
outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
outValue.changingConfigurations);
if (outValue.type == TypedValue.TYPE_STRING) {
outValue.string = mApkAssets[cookie - 1].getStringFromPool(outValue.data);
}
return true;
}
}
private static native int nativeGetResourceValue(long ptr, @AnyRes int resId, short density,
@NonNull TypedValue outValue, boolean resolveReferences);
最终呢,调用到了nativeGetResourceValue。
总结:查找资源从Context开始到Context内部的Resources,再到Resources的成员ResourcesImpl,再到ResourcesImpl的成员AssetManager,最终呢,到大native层,到这一步,我们可以说资源实际上是由AssetManager管理的。
那么,AssetManager又是如何来的呢?
继续往下看应用资源加载原理
android资源加载原理
我们从Activity的创建开始,一步步看他的资源是如何加载出来的
ActivityThread.handleLaunchActivity
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {

最低0.47元/天 解锁文章
2万+





