欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 6.0与9.0 加载WebView Resource 的区别

程序员文章站 2022-06-04 15:07:01
...

从前两篇文章里面我们分析了 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分离的方式