RePlugin插件启动源码分析

作者: QinGeneral | 来源:发表于2018-02-16 13:31 被阅读64次
    图片取自zoommy

    大年初一,先祝各位新年快乐!今天还在看博客学习的兄dei很强大,如果能把一年节日假期时间分配到自己成长上,那你的一年 = 别人一年 * 1.1。如果能够做到年年如此,10年后你就相当于活了11年。而这期间,学习复利效应的效果是呈现指数增长的。当然,朋友关系也不能落下,但在节假日做无聊的事情就是浪费时间了。

    之前搭建了RePlugin源码阅读环境,详情请参考博客RePlugin阅读源码环境搭建

    今天来分析一下RePlugin启动插件(RePlugin.startActivity)的流程。

    下图是我用StarUML画的时序图-SequenceDiagram,简单表现了RePlugin.startActivity调用后发生的事情及其先后顺序。

    RePlugin插件启动时序图

    下面进行详细分析。

    1. RePlugin.startActivity

    RePlugin中启动插件,就是通过调用以下方法。

    RePlugin.startActivity(context, intent);
    
    // 或者
    
    RePlugin.startActivity(context, intent, pluginName, activity);
    

    RePlugin是一个有很多静态方法的类。集成了安装卸载插件、启动插件等功能。使用RePlugin框架,一般来说只需要操作RePlugin类就行。

    2. Factory.startActivityWithNoInjectCN

    这两个startActivity方法,最终都会调用

    Factory.startActivityWithNoInjectCN(context, intent, plugin, activity, process);
    

    startActivity(context, intent, pluginName, activity)方法,中间多了一步,就是给intent设置ComponentName。会先调用以下方法初始化componentName,然后调用startActivityWithNoInjectCN方法。

    Factory.startActivity
    

    Factory是框架内部的一个工具类,主要集成了查询插件、查询插件资源、查询Activity信息、加载插件等功能。在启动插件中,Factory中所做的工作就是设置ComponentName给Intent。其中ComponentName主要包括两个属性:pkgName和clsName。这两个属性和插件属性对应关系:pkgName == pluginName、clsName == activityName。

    startActivityWithNoInjectCN方法的代码如下:

    boolean result = sPluginManager.startActivity(context, intent, plugin, activity, process);
    
    RePlugin.getConfig().getEventCallbacks().onStartActivityCompleted(plugin, activity, result);
            
    

    startActivityWithNoInjectCN就包括两部分,第一行代码是直接调用PluginCommImpl的startActivity方法启动Activity,这个在下一部分继续说。

    第二行是调用RePluginConfig的方法回调,告知已经启动Activity。这里的RePluginConfig回调,是可以在自己宿主的application中设置的。设置回调后,就可以在application中进行各个事件的处理,比如插件安装失败事件回调方法onInstallPluginFailed。以官方samplehost代码为例,设置回调的代码如下。

    // SampleApplication.java
    
    repluginConfig.setEventCallbacks(new HostEventCallbacks(this));
    
    3. PluginCommImpl.startActivity

    Factory.startActivityWithNoInjectCN中,调用了pluginCommImpl.startActivity方法,而在此方法中没有做任何实质的工作,直接调用了PluginLibraryInternalProxy.startActivity方法。

    4. pluginLibraryInternalProxy.startActivity

    PluginLibraryInternalProxy是最终实现启动插件的地方,也是做了最多工作的地方。流程图见下图。

    pluginLibraryInternalProxy.startActivity流程图

    在PluginLibraryInternalProxy中,先判断download标签和plugin是否为null。download标签默认为true,目前没有手动修改的办法。如果判断成立,则回调application中的方法。

    然后判断是否是动态类,是的话设置Intent、启动Activity即可。否则进入下一步。

    如果插件还没有加载,调用onLoadLargePluginForActivity方法加载插件。然后初始化ComponentName,设置Intent,调用context.startActivity启动插件中指定的Activity。最后调用回调方法,通知application已经启动完毕。

    总结

    这样来看,RePlugin启动插件,也就是RePlugin.startActivity方法的调用过程,最终还是调用context.startActivity方法实现的。RePlugin框架所做的就是对Activity的pkgName、activityName进行处理:使用这两个属性创建ComponentName,并传递给Intent;以及在启动插件的不同时期,对RePluginConfig的回调,如未找到插件时会回调onPluginNotExistsForActivity方法。

    最后,RePlugin启动插件可以说是RePlugin框架源代码的入口,接下来会对插件安装、卸载等功能的源码进行分析,以此一步步的对RePlugin框架整体建立系统的认识,对RePlugin的实现机制有所了解。学习框架中的设计模式,最终能够应用到自己的代码中去。

    版权声明
    本文首发自简书:搜索作者 QinGeneral
    同步发于CSDN博客:搜索作者 迷失
    同步发于微信公众号:AndroidRain
    无需授权即可转载,甚至无需保留以上版权声明;
    转载时请务必注明作者。

    相关文章

      网友评论

        本文标题:RePlugin插件启动源码分析

        本文链接:https://www.haomeiwen.com/subject/kjrptftx.html