Android 6.0与9.0 加载WebView Resource 的区别
从前两篇文章里面我们分析了 6.0的资源管理机制和9.0的资源管理机制
先说以下6.0的
根据6.0 ResourceManager的代码 我们先做一个测试
编写如下代码 我们将mActiveResources中保存的内容打印出来
ResourcesManager resourcesManager = ResourcesManager.getInstance();
//6.0打印
try {
ArrayMap<Object, WeakReference<Object>> map = Reflector.with(resourcesManager).field("mActiveResources").get();
for (int i = 0; i < map.size(); i++) {
Object a = map.keyAt(i);
Object b = map.valueAt(i).get();
System.out.println(Reflector.with(a).field("mResDir").get());
System.out.println(b.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
打印输出
10-12 15:47:02.816 10785-10785/com.vivo.res_manager_study I/System.out: /data/app/com.vivo.res_manager_study-1/base.apk
10-12 15:47:02.816 10785-10785/com.vivo.res_manager_study I/System.out: [email protected]
可以看到当前包的Resources已经被加入到mActiveResources中了
再修改代码
在打印之前添加webView初始化
WebView webView = new WebView(context);
打印输出
10-12 15:48:48.586 10985-10985/com.vivo.res_manager_study I/System.out: /data/app/com.google.android.webview-1/base.apk
10-12 15:48:48.586 10985-10985/com.vivo.res_manager_study I/System.out: [email protected]
10-12 15:48:48.586 10985-10985/com.vivo.res_manager_study I/System.out: /data/app/com.vivo.res_manager_study-2/base.apk
10-12 15:48:48.586 10985-10985/com.vivo.res_manager_study I/System.out: [email protected]
可以看到添加了webView初始化代码之后 mActiveResources中增加了一个Resources实例,该实例指向webView组件安装路径
WebView就是从这个Resources取到了自己所需要的资源
这也是7.0以下版本中替换Activity和Application的Resources不会出现Web组件崩溃的原因,因为在这个level的系统中,web组件资源与主apk资源是分离的
OK 分析完6.0的再看9.0的
9.0的ResourceManager相对复杂 我们也是使用反射的方法将两种情况下的ResourceManager数据打印出来
编写打印代码
System.out.println(" 打印 mResourceImpls 中缓存的 ResourceImpl");
ResourcesManager resourcesManager = ResourcesManager.getInstance();
// 9.0源码
try {
ArrayMap map = Reflector.with(resourcesManager).field("mResourceImpls").get();
for (int i = 0; i < map.size(); i++) {
Object key = map.keyAt(i);
WeakReference value = (WeakReference) map.get(key);
System.out.println(value.get() + " " + key);
}
} catch (Reflector.ReflectedException e) {
e.printStackTrace();
}
System.out.println(" 打印 mActivityResourceReferences 中缓存的 Activity Resources");
try {
WeakHashMap<Object, Object> map = Reflector.with(resourcesManager).field("mActivityResourceReferences").get();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object activityResources = entry.getValue();
ArrayList<WeakReference<Resources>> list = Reflector.with(activityResources).field("activityResources").get();
for (WeakReference<Resources> weakReference : list) {
Resources resources = weakReference.get();
Object resourcesImpl = Reflector.with(resources).field("mResourcesImpl").get();
System.out.println(resourcesImpl);
}
}
} catch (Exception e) {
e.printStackTrace();
}
在这份打印代码中 我们输出了mResourceImpls和mActivityResourceReferences中的数据 不理解这两个缓存作用的可以去看之前的文章
打印输出
I/System.out: 打印 mResourceImpls 中缓存的 ResourceImpl
I/System.out: [email protected] ResourcesKey{ mHash=8a5fac6a mResDir=null mSplitDirs=[] mOverlayDirs=[] mLibDirs=[] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=bafccb1 mResDir=/data/app/com.vivo.res_manager_study-_k1QRBE8jUyrPTVnJDIbsA==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=30333beb mResDir=/data/app/com.vivo.res_manager_study-_k1QRBE8jUyrPTVnJDIbsA==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar] mDisplayId=0 mOverrideConfig=en-rUS-ldltr-sw360dp-w360dp-h752dp-normal-long-notround-lowdr-nowidecg-port-notnight-xxhdpi-finger-keysexposed-nokeys-navhidden-nonav-v28 mCompatInfo={480dpi always-compat}}
I/System.out: 打印 mActivityResourceReferences 中缓存的 Activity Resources
I/System.out: [email protected]
根据 mActivityResourceReferences中AcitvityResource 我们找到对应的ResourcesImpl并且根据ResourceKey得知了ResourcesImpl中的内容
mResDir=/data/app/com.vivo.res_manager_study-_k1QRBE8jUyrPTVnJDIbsA==/base.apk
mSplitDirs=[]
mOverlayDirs=[]
mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar]
mDisplayId=0
mOverrideConfig=en-rUS-ldltr-sw360dp-w360dp-h752dp-normal-long-notround-lowdr-nowidecg-port-notnight-xxhdpi-finger-keysexposed-nokeys-navhidden-nonav-v28 mCompatInfo={480dpi always-compat}}
下面我们在打印代码之前添加初始化webView的源码
new WebView(MainActivity.this);
System.out.println(" 打印 mResourceImpls 中缓存的 ResourceImpl");
ResourcesManager resourcesManager = ResourcesManager.getInstance();
// 9.0源码
try {
ArrayMap map = Reflector.with(resourcesManager).field("mResourceImpls").get();
for (int i = 0; i < map.size(); i++) {
Object key = map.keyAt(i);
WeakReference value = (WeakReference) map.get(key);
System.out.println(value.get() + " " + key);
}
} catch (Reflector.ReflectedException e) {
e.printStackTrace();
}
System.out.println(" 打印 mActivityResourceReferences 中缓存的 Activity Resources");
try {
WeakHashMap<Object, Object> map = Reflector.with(resourcesManager).field("mActivityResourceReferences").get();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object activityResources = entry.getValue();
ArrayList<WeakReference<Resources>> list = Reflector.with(activityResources).field("activityResources").get();
for (WeakReference<Resources> weakReference : list) {
Resources resources = weakReference.get();
Object resourcesImpl = Reflector.with(resources).field("mResourcesImpl").get();
System.out.println(resourcesImpl);
}
}
} catch (Exception e) {
e.printStackTrace();
}
打印输出
I/System.out: 打印 mResourceImpls 中缓存的 ResourceImpl
I/System.out: [email protected] ResourcesKey{ mHash=8a5fac6a mResDir=null mSplitDirs=[] mOverlayDirs=[] mLibDirs=[] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=25ddf2aa mResDir=/data/app/com.vivo.res_manager_study-sVY46cDW2JT2hEkohn2GJw==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/base.apk] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=4114b0be mResDir=/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/base.apk mSplitDirs=[/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_autofill_assistant.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_autofill_assistant.config.en.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_autofill_assistant.config.in.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_autofill_assistant.config.ms.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_autofill_assistant.config.zh.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_config.en.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_config.in.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_config.ms.apk,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/split_config.zh.apk] mOverlayDirs=[] mLibDirs=[] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=4a6161e4 mResDir=/data/app/com.vivo.res_manager_study-sVY46cDW2JT2hEkohn2GJw==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar,/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/base.apk] mDisplayId=0 mOverrideConfig=en-rUS-ldltr-sw360dp-w360dp-h752dp-normal-long-notround-lowdr-nowidecg-port-notnight-xxhdpi-finger-keysexposed-nokeys-navhidden-nonav-v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=578cb784 mResDir=/data/app/com.vivo.res_manager_study-sVY46cDW2JT2hEkohn2GJw==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar] mDisplayId=0 mOverrideConfig=v28 mCompatInfo={480dpi always-compat}}
I/System.out: [email protected] ResourcesKey{ mHash=7c1026be mResDir=/data/app/com.vivo.res_manager_study-sVY46cDW2JT2hEkohn2GJw==/base.apk mSplitDirs=[] mOverlayDirs=[] mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar] mDisplayId=0 mOverrideConfig=en-rUS-ldltr-sw360dp-w360dp-h752dp-normal-long-notround-lowdr-nowidecg-port-notnight-xxhdpi-finger-keysexposed-nokeys-navhidden-nonav-v28 mCompatInfo={480dpi always-compat}}
I/System.out: 打印 mActivityResourceReferences 中缓存的 Activity Resources
I/System.out: [email protected]
同样 根据 mActivityResourceReferences中AcitvityResource 我们找到对应的ResourcesImpl并且根据ResourceKey得知了ResourcesImpl中的内容
mResDir=/data/app/com.vivo.res_manager_study-sVY46cDW2JT2hEkohn2GJw==/base.apk mSplitDirs=[]
mOverlayDirs=[]
mLibDirs=[/system/framework/org.apache.http.legacy.boot.jar,
/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/base.apk]
mDisplayId=0
mOverrideConfig=en-rUS-ldltr-sw360dp-w360dp-h752dp-normal-long-notround-lowdr-nowidecg-port-notnight-xxhdpi-finger-keysexposed-nokeys-navhidden-nonav-v28
mCompatInfo={480dpi always-compat}
对比没有添加webview 实例化之前的代码 我们发现mLibDirs中新增了
/data/app/com.android.chrome-dO2jAeCdfgkLjVHzK2yx0Q==/base.apk
从7.0开始 android将Web组件资源作为libDir添加至Assert中,用于资源查找,没有完全使用Resource分离的方式