之前做的项目是RN的项目,最近在将之前的项目用Android组件化重构一遍 + 白天还得工作。真的是忙的要命,再加上自己十一点之前肯定上床睡觉的“坏习惯”, 没办法只能在中秋节的今天来继续学习插件化。 祝各位小伙伴:中秋快乐!
之前学习了宿主APP如何加载插件APK,本篇博客学习:宿主APP加载插件APK的资源。
因为我们平时用Activity的居多,并且每个Activity都会调用各种资源,因此学习本篇博客还是很有必要的。
Android中的资源分为两类:
- res目录下存放的是可编译的资源文件。编译时系统会自动在R.java中生成资源文件的十六进制。
- assets目录下存放的是原始资源文件。APK编译的时候不会编译assets下的资源文件。因此我们要访问这些资源,只能通过AssetManager类来达到目的。
关于AssetManager,可能会有点陌生,说实话我自己在学习插件化之前,真的是压根用都没用过。 这里我捎带提一下。
**
Resources 和 AssetManager
**
对于Resources 我们可能不会陌生,我们经常用getString, getText等方法, 但是看下源码就会知道,最终调用的还是AssetManager中的私有方法。
@NonNull public CharSequence getText(@StringRes int id) throws NotFoundException {
CharSequence res = mResourcesImpl.getAssets().getResourceText(id);
if (res != null) {
return res;
}
throw new NotFoundException("String resource ID #0x"
+ Integer.toHexString(id));
}
public AssetManager getAssets() {
return mAssets;
}
而AssetsManager 直接对接Android系统底层。
Assets Manager有一个方法:addAssetPath(String path) 方法,app启动的时候会把当前的APK路径传递进去,然后我们就可以访问资源了。
我们可以通过反射获取到addAssetPath方法,并且将插件APK路径传递进去。 apk插件有几个,我们就调用几次addAssetPath,把插件的资源都放入到一个资源池中
PS: 资源池也就是:resources.arsc 文件,它是一个Hash表,存放着十六进制和资源的对应关系。
**
调用插件的资源文件
**
首先建议先看下怎样加载插件APK:
Android 插件化开发——宿主APP加载APK插件
我们接着添加代码:首先在插件项目MyPluginProject中创建一个类:
package com.liumengqiang.mypluginproject;
import android.content.Context;
import com.liumengqiang.interfacelibrary.IBaseInterface;
/**
* author: liumengqiang
* Date : 2019/9/13
* Description :
*/
public class TestResource implements IBaseInterface {
@Override
public String getStringForResId(Context context) {
return context.getResources().getString(R.string.test_string);
}
@Override
public void setName(String name) {
}
@Override
public String getName() {
return null;
}
}
public interface IBaseInterface {
void setName(String name);
String getName();
String getStringForResId(Context context);
}
然后打包(“app-debug.apk“), 将该APK还是复制到宿主项目的assets目录下:
先将APK加载到存储内存
@