• 反射机制,热更新,插件化


    1:Java 文件执行的过程:
     .java文件经过编译生成.class文件,虚拟机识别class,将类加载到内存,翻译成机器码给底层的操作系统
    其中虚拟机识别class的过程用到的就是类加载器。
     
    2:类加载器包括pathClassLoader和dexClassLoader,他们的父加载器是BootClassLoader。
     
    3:所有应用都是通过classLoader加载到内存的,那pathClassLoder和dexClassLoader本身也是个类,在应用启动的时候,已经被加载到内存中。
     
    4:双亲委托机制:
           加载类用的是双亲委托机制,一个类要被加载,先看BootClassLoader是否能够加载(BootClassLoader主要加载系统级别的类),如果无法加载,在通过pathClassLoader或者dexClassLoader加载。这样做的好处是,当我们定义一个和系统名字一样的类的时候,因为系统类前面已经被加载过了,所以不会加载我定义的这个类,就无法替换系统类。这里面涉及到一个缓存的问题,其实他的加载顺序是这样的,先查找pathClassLoader的缓存是否之前加载过这个类,为空的话,再查找父加载器BootClassLoader的缓存,为空的话,继续查找父加载器的缓存,直到最顶层。都为空的话,开始从最顶层的父类尝试去加载这个类,如果失败,那么下一层的子类去加载,一直到最下面一层的子类。当一个类被加载之后,会被保存到相应的缓存,下次再碰到这个类的话,不需要重新加载,直接从缓存取出。
     
    5:反射机制:
      通过反射机制,我们可以获取任意一个类的属性和方法,包括private的属性和方法。
      对于private的理解:Java设计private的初衷不是为了我们绝对不能用相应的属性和方法,而是担心我们对于该类的没有把握,而希望一些属性和方法不被我们误用,是一种安全保护机制。我们通过反射获取这些private的属性和方法的前提是,我们有足够的信心保证可以正确的使用这些属性和方法。
     
    6:热修复、插件化原理:
      1)所有应用都是通过classLoader加载到内存的,pathClassLoader里面有一个pathList,pathList里面有一个dexElements,dexElements就是dex文件存储在里面。pathClassLoader的loadclass加载的过程就是遍历dexElements里面的dex,dex其实就是.class文件,然后加载这些.class文件。
         2)热修复就是把我们修改好后的apk,封装成新的dexElements,通过反射机制,替换掉原来的dexElements,那么这样加载器在加载的时候,加载到的那个class是我们修复后的class,达到修复的目的。
         3)热修复的操作最好是放在application里面,这样程序一启动就会去加载修复的类,不这样做的问题是:
    如果放在其他地方,在程序执行到这个地方的时候,原先错误的那个类可能已经被加载了,已经被存到缓存里面了。当你重启应用,执行的永远都是错误的那个类,你的修复类都不会被执行到。原理就是上面说的,会先去找缓存看是否加载过该类。
     
    7:插件化:
    这其中关系到两次的进程间通信:
    1)应用调用AMS
    系统的服务都是实现了Binder的服务端,应用进程要想和它通信需要获取它的代理端。
    2)AMS到应用

    在创建一个新的应用进程之后,系统首先会启动ActivityThread,ActivityThread是应用进程的主线程,在ActivityThread创建的时候会创建一个ApplicationThread的对象。这个ApplicationThread实现了一个Binder的服务端。新的进程创建完成之后通知AMS服务的之后同时把自己进程的ApplicationThread的代理端送给AMS服务。AMS服务中保存了所有应用进程的ApplicationThread的代理对象。所以AMS要想给应用进程发送消息,只需要得到目标应景进程的ApplicationThread的代理端对象即可。

     滴滴插件化方案:https://github.com/didi/VirtualAPK

    Activity:假设要启动插件中的Activity1,我们伪装一个Activity2骗过系统,预先注册在AndroidManifest.xml中,占个坑;

    1)创建一个VasIinstruentation,通过反射机制和代理模式,替换掉系统中的Instrumentation,所有经过Instrumentation的操作都会到VasInstumentaion替代掉。

    2)这时startActivity是在VasInstrumentation中执行,startActivity实际会调用到AMS中执行,因为AMS会对要启动的Activity1是否注册过进行校验。我们先保存Activity1的信息,然后告诉AMS我们要启动的是startActivity2。AMS看到启动的是Activity2,就通过校验。

    3)AMS的作用:

         a:对Activity的注册进行校验

         b:栈的调度

         c:AMS作为服务端,进行生命周期的管理,Client端的ActivityThread负责响应各个生命周期

    4)AMS启动Activity2之后,根据上面流程图可知,最终会回到应用的mInstrumentation.newActivity(),newActivity通过类加载器生成实际上的Activity对象,我们的VasInstrumentation就可以对该方法进行重写,把原来实际要启动的Activity1的信息重新提取出来,替换掉当前的Activity2,生成Activity2对象,就完成了正常的Activiyt1启动。

     
     
     
  • 相关阅读:
    String.Format使用方法
    在gfs2中关闭selinux
    开发板怎样开启telnet服务
    Google App Engine 学习和实践
    Ewebeditor最新漏洞及漏洞大全
    为HttpStatusCodeResult加入customErrors
    【android】下载文件至本应用程序的file文件夹或者sdcard
    java entry
    关闭对话框,OnClose和OnCancel
    主成分分析(PCA)
  • 原文地址:https://www.cnblogs.com/wnpp/p/16053088.html
Copyright © 2020-2023  润新知