本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!
1.0版本:2016-05-21
SubClass!!
执行结果说明一个问题:子类调用父类变量的时候,子类没有初始化,因为此时的代码关系跟子类无关;子类初始化的时候,父类也没有再初始化,因为父类在当前方法体中已经初始化过了。接口与父类的唯一区别在于,接口初始化不会要求父接口,只有用到父接口才会初始化,同样的都会生成<clinit>类构造器。
这个时候加载类构造器<clinit>,会初始化类中所有变量,当然父类先于子类初始化
6、使用 加载完之后,该怎么样调用怎么样调用,TextView设置文字,ImageView设置图片等等
7、卸载 类不再被调用,如类被GC回收,虚拟机退出。
两个类是否相等,主要在于第一使用同一个加载器加载,第二全限定名地址一致
为什么要提出上面的问题呢?接下来要讲讲虚拟机的一个加载机制。
在虚拟机的角度来看,有两种类加载器,一种叫系统加载器(Bootstrap ClassLoader),一种叫自定义加载器(extends ClassLoader),这种呢又分为两个,一种叫应用加载器,一种叫扩展类加载器,一般默认为前者;而我们的应用程序加载主要由上面三个加载器相互配合完成的。三者的关系如Application-->Extension-->Bootsrap,双亲委派机制是指两两以组合的方式,子加载器先去调用父加载器的方法,没找到目标对象再去用子加载器
伪代码如下:
loadClass(String name,boolean resolve){
Class c=findLoadedClass()
if(c==null){
try{
if(parent !=null)
c=parent.loadClass(name,false);
else
c=findBootstrapClassOrNull(name);
}catch(ClassNotFoundException e){ }
}
if(c==null)
c=findClass(name);
}
Java提倡我们去把自己调用类的逻辑写在findClass里,这样有助于双亲委派机制的正常使用。
破坏1、重写loadClass
破坏2、使用线程上下文加载器去让父加载器去调用子加载器的方法
破坏3、热加载 现在常用的做法是自定义类加载器并将原bug模块覆盖-OSGI
但由于自定义加载器之间的规则如果混乱,出现同时互相引用的问题,那么会最终找不到类,而出现线程死锁和内存泄露的问题。
关于热修复,也被称为插件,目前比较流行的有HotFix、Nuwa、DroidFix、AndFix等,这些框架均可以在github或其他地方找到,原理如上,方法多样,有覆盖的、有重定向的等等,通过配置、设置action等方式;而作为插件需要满足以下条件:
1、可以独立安装,但不可独立运行
2、具有向下兼容性,即可拓展性
3、只能运行在宿主程序中,而且可以被禁用、替换
使用场景包括修复线上bug、做手机皮肤、开发应用商店等系统提供的接口
下一节我们会讨论一下线程并发的问题。
Tinker后台搭建:https://github.com/baidao/tinker-manager
Android6.0以后的内联策略会给热修复带来一定的影响:http://dwz.cn/4O15FS