现在的位置: 首页 > 综合 > 正文

自定义View在layout中的构造实例Constructor被缓存

2018年01月17日 ⁄ 综合 ⁄ 共 796字 ⁄ 字号 评论关闭

  

    最近在搞插件,而插件用dexClassloader加载,每次退出会将其销毁,重载context中的getClassLoader()方法来保证下次取得新加载的类;

    但是这样做的会会出现一个问题:在布局的layout文件中静态加载自定义的view;第一次进入时没有问题,第二次进入时findViewById获取view,在强制转换自定义的view报以下的错误:Caused by: java.lang.ClassCastException:但是打印出来的log看到的类名字跟准备要强制转换的类型是一样的;

   google半天发现点线索是同一个类在不同的classloader加载出来的类被认为是不等的,但是在classload中已经加载出来的类是没有办法手动来更新的和销毁;从现象来看可以从虚拟机类的加载机制和加载资源这块查下;

  再次试验把静态加载的自定义类的改用动态在加载,发现没有问题;因此可能是在布局文件这块加载出了问题,在块的加载可以参考以下的网址:

http://blog.sina.com.cn/s/blog_61fbf8d101016eve.html来学习;

  最终在LayoutInflater.java的方法createView中发现猫腻:

        sConstructorMap是这类的静态变量map,相当于cache功能:每次在生成对应得view时都会来这里去取下,没有的则去用getClassLoader去加载,完后会把这个构造出来的实例放到这里;有的话则从这里取对应的实例;问题就在这里

    解决思路清空这个map,具体:LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);然后通过反射获取这map,再清空非系统类的控件就ok了。

  

抱歉!评论已关闭.