[TOC]
前言
“二八定律”在软件行业也有体现,甚至更为极端。据说90%的代码在平时都不会运行到。比如异常处理、分支条件,或者是为了可维护性做的大量封装。这些代码是必须存在的,但对于开源框架的使用者,初次打开源码一般梳理清楚主流程就足够了,这些长篇代码却往往变成了阻碍阅读的干扰项。让我们回归初心,用最简单的伪代码(pseudo code)剥茧抽丝,对我自己而言,也希望这个系列能坚持下去,让更多的人减少阅读源码的痛楚。
注:本文所使用VirtualApk
的源码版本为0.9.8.6【TODO 引用地址】
调用
VirtualApk
的demo在调用时不可避免要跟文件I/O、权限申请打交道,并且代码分布在Application
和Activity
之中。整理过后的伪代码是:
/**
* 伪代码(pseudo code), 不要用于实际开发
*/
// 初始化PluginManager, 并加载插件Apk, file是插件Apk的存储路径
PluginManager.getInstance(context).loadPlugin(file);
// 启动Activity, Service的启动也是一样
Intent intent = new Intent();
intent.setClassName(context, "com.plugin.apk.fqcn.PluginTargetActivity");
startActivity(intent);
伪代码体现出的:
- 框架暴露给我们的API是
PluginManager
类,常见的门面(Facade)+单例(Singleton)设计模式; - 启动插件Apk里的某个
Activity
和正常启动项目Activity
的方式类似,都是通过创建指向目标Activity
的Intent
,最后调用startActivity(intent)
完成调用; - 区别在于启动插件
Activity
无法传入class<?>
类型的参数,需要用String
类型代替,这点与启动常规Activity
不同(直观原因是宿主项目无法引用到插件项目中的class
,另一个不那么直观的原因是插件class
使用了不同的ClassLoader
加载,后续会讲到); - 注释表明启动
Service
的方式和Activity
相同,都是通过intent.setClassName()
和startActivity(intent)/startService(intent)
;
伪代码没有体现出的:
- 官方demo还调用了
PluginManager.init()
方法,暂且认为是个空实现忽略它; - demo还演示了插件
ContentProvider
的使用方法,鉴于大部分情况不使用就不在本篇写了;
具体代码在VirtualApk/app
目录下,VAApplication
和MainActivity
两个类。【TODO 引用地址】
网友评论