GeorgeYang'Blog

my technology blog


问题出现原因:

插件技术动态加载View需要实例化一个LayoutInflater,但6.0以后com.android.internal.policy.PolicyManager被去除,导致插件view无法被创建,为了能让我的app能够在6.0系统上运行,我必须解决掉这个bug

解决办法:

搜素源码找到这个类: https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r25/core/java/com/android/internal/policy/PhoneLayoutInflater.java 可以通过实例化它取得LayoutInflater,具体代码如下: 博客出处

 policyClass = Class.forName("com.android.internal.policy.PhoneLayoutInflater");
 Constructor<?> localConstructor = policyClass.getConstructor(new Class[]{Context.class});
 mLayoutInflater = (LayoutInflater) localConstructor.newInstance(new Object[]{context});

如果你的项目需要经过com.android.internal.policy.PolicyManager获取windows

 Class windowClass = Class.forName("com.android.internal.policy.PhoneWindow");
 Constructor<?> localConstructor = windowClass.getConstructor(new Class[]{Context.class});
 Window windows = (Window) localConstructor.newInstance(new Object[]{getApplicationContext()});//实例化Window,如果传的context不是Application的Context,就会奔溃
 Field field = windowClass.getDeclaredField("mLayoutInflater");
 field.setAccessible(true);
 mLayoutInflater = (LayoutInflater) field.get(windows);//取得Application的LayoutInflater,而不是插件的LayoutInflater

 //往windows设置插件的LayoutInflater
 policyClass = ReflectUtil.getClass("com.android.internal.policy.PhoneLayoutInflater");
 Constructor<?> policyLocalConstructor = policyClass.getConstructor(new Class[]{Context.class});
 mLayoutInflater = (LayoutInflater) policyLocalConstructor.newInstance(new Object[]{this});
 field.set(windows,mLayoutInflater);

参考源码:

https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r25/core/java/com/android/internal/policy/PhoneWindow.java

热更新及插件技术实践

一款插件技术和热修复技术集一身的app:百宝工具箱

如果需要源码,请联系我

搜索到一些有趣的东西:

5.1.1到6.0源码改动列表

android全套源码,更新到6.0.0

android全套源码,更新到6.0.0,百度下载地址