简介

插件模块是Small特有的插件化与IDE完美结合的产物,做到了“模块即组件,组件即插件”。 组件是工程的角度,插件是应用的角度。只有做到了清晰的组件解耦,才能更好的拆分插件模块。

出于业务需求考虑,Small定义了两类插件:公共库插件与应用插件。应用插件相对简单,就是用来把大应用拆分成一个个小的业务单元,公共库插件则是为这些业务单元提供公共的代码与资源。

通过设定 URI,宿主、本地化应用插件、本地化web插件、在线网页,以及任何自定义的插件之间能够相互调起与传递参数。

目前已支持 Android 、iOS 以及 HTML5 插件。并且三者之间可以通过同一套 JavaScript 接口进行通信。

开发基础

通过 build.gradle 集成 Small,项目的build.gradle文件中

buildscript {

repositories {

jcenter()

}

dependencies {

...

classpath 'net.wequick.tools.build:gradle-small:1.2.0-beta3'

}

}

...

apply plugin: 'net.wequick.small'

small {

aarVersion = '1.2.0-beta3'

}

通过 自定义Application 初始化 Small,app > java > com.example.mysmall > SmallApp中

public class SmallApp extends Application {

public SmallApp() {

// Small框架初始化

Small.preSetUp(this);

}

}

AndroidManifest.xml中

android:name=".SmallApp"

...>

创建插件模块 App.main,注意包名为com.example.app.main

通过 buildLib,buildBundle 编译 Small 插件,命令后面可添加 -Dbundle.arch=x86

gradlew buildLib -q

gradlew buildBundle -q

通过 bundle.json 配置插件路由,右键 app 模块,New > Folder > Assets Folder 新建 assets 目录,在新建配置文件bundle.json内容如下

{

"version": "1.0.0",

"bundles": [

{

"uri": "main",

"pkg": "com.example.appmain"

}

]

}

通过 Small.openUri 启动插件,宿主的 app > java > com.example.mysmall > MainActivity中

@Override

protected void onStart() {

super.onStart();

// Small插件初始化

Small.setUp(this, new Small.OnCompleteListener() {

@Override

public void onComplete() {

// 通过uri启动插件

Small.openUri("main", MainActivity.this);

}

});

}

创建公共库插件模块 Lib.style,注意包名为com.example.lib.style,将app.main/src/main/res/values 下除了strings.xml的文件移动到lib.style/src/main/res/values 目录下,修改 lib.style/src/main/res/colors.xml中colorPrimary值为#2FA739

添加公共库引用,修改 app.main/build.gradle,增加对 lib.style 的依赖

dependencies {

...

compile project(':lib.style')

}

添加插件路由

"bundles": [

...

{

"pkg": "com.example.libstyle"

}

]

重新运行

gradlew cleanLib -q

gradlew buildLib -q

gradlew buildBundle -q

工程结构图

工程目录结构(转)

宿主:工程中的app模块,不能依赖lib.xxx

assets目录下的bundle.json声明宿主使用的插件,每个bundle可定义一些rule去启动特定的Activity

可增加签名配置和共享的依赖库

signingConfigs {

release {

storeFile file('../sign/release.jks')

storePassword "5mall@ndro!d"

keyAlias "small"

keyPassword "5mall@ndro!d"

}

}

buildTypes {

release {

signingConfig signingConfigs.release

}

}

[...]

compile 'com.android.support:design:23.1.1'

公共库插件:工程中的lib.xxx模块,是标准的Android库工程

第三方依赖合并到lib.vendor中管理

样式相关的资源放在lib.style中管理

其它工具类,以及网络、存储等跨业务模块的底层代码可以在lib.utils中管理

可以通过compile project(':插件模块名')来被应用插件模块所引用

编译时(buildLib)会被打包成为一个可独立更新的插件

业务插件:工程中的app.xxx模块,是标准的Android应用工程

app.main一般是程序的入口,并控制业务逻辑的主线

其他app.xxx一般是业务逻辑的支线,插件内的业务逻辑之间关联性较强

app.xxx可以依赖多个lib.xxx

可独立运行、独立更新

宿主分身模块:工程中的app+xxx模块,是标准的Android应用工程

分身是宿主的一部分,最终编译到宿主中,不可被独立更新

具备占坑(stub)的功能,即在宿主中预留特定的(无法插件化的)资源、代码或manifest项目,使系统可以正常识别,任何稳定的资源、代码、第三方库也可使用分身下沉到宿主中,以减少插件体积

它提供了可以让插件模块自由访问其中的资源与代码的能力,并为所有插件模块添加该依赖

需要占坑的项目为

必须在宿主Manifest注册的项目,包括:所有权限,受限 Activity,任何 Provider、Service、BroadcastReceiver

必须在宿主占坑的资源,包括:转场动画、通知栏图标、自定义视图、桌面快捷方式图标

web插件工程:工程中的web.xxx模块,本地网页组件

常用命令

gradlew samll # 查看编译情况

gradlew buildLib -q # 编译公共库插件,不仅编译了lib.xxx,还编译了宿主模块

gradlew buildBundle -q # 编译业务插件

gradlew -p app.main assembleRelease # 单独编译一个插件app.main

gradlew cleanLib -q # 清除公共库

gradlew cleanBundle -q # 清除业务库

其中-q是安静模式,可以让输出更好看,也可以不加。对插件的编译,会在app/smallLibs/生成对应的so文件,这些so文件本质上就是独立的apk包。

常用API

// 框架初始化

Small.preSetUp(this);

// 在宿主的 Application 里指定是否从 assets 读取插件,有build.gradle 中 buildToAssets的值指定

Small.setLoadFromAssets(BuildConfig.LOAD_FROM_ASSETS);

// 设定基本的跳转地址

Small.openUri("https://github.com/wequick/Small/issues", MainActivity.this);

// 更新bundles.json和version信息

Small.updateManifest(info.manifest, false)

// 获取补丁文件目录

net.wequick.small.Bundle bundle = Small.getBundle(u.packageName);

File file = bundle.getPatchFile();

// 使更新后的插件生效

bundle.upgrade();

// 暗度插件意图

Small.wrapIntent(intent);

// 创建远程fragment

Small.createObject("fragment-v4", sUris[position], MainActivity.this);

// 设置网页的基本回调

Small.setWebViewClient(new MyWebViewClient());

// TODO

Small.getBundleVersions()

// TODO

Small.setWebActivityTheme(R.style.AppTheme);

// TODO

Small.getIsNewHostApp()

其它

对插件的编译,会在app/smallLibs/生成对应的so文件,这些so文件本质上就是独立的apk包,所以修改某个模块之后,要在运行时生效,必须先编译对应的插件,更新smallLibs下的.so文件

编译后的lib,如果删除资源再编译就会出现错误“No support deleting resources on lib.* now!”,所以在删除lib中的资源后,需要删除lib.xxx模块下的public.txt再通过cleanLib, buildLib, cleanBundle, buildBundle重新编译

从插件初始化,到初始化完成会耗费几百毫秒,甚至更多可以考虑将欢迎页放入宿主工程之中,如果欢迎页有比较复杂的广告逻辑或统计相关的逻辑,则可以考虑在主插件中做一个透明的Activity来处理

关于插件的Manifest,可以在插件的Manifest中指定application,每个插件的Application都会在Small.setup时被创建;对于需要处理android:configChanges的Activity需要在宿主中注册;如果要通过uri启动Activity,则对应Activity应该Manifest中进行注册,如果需app插件可以独立运行,但在Manifest中至少要注册一个主Activity

热更新?

打开项目的app工程也就是入口工程,文件夹里有一个smallLibs文件夹,里面有一个armeabi文件,里面是.so文件,这些文件就是通过buildLib和buildBundle来把非宿主的app中的文件打包成的.so文件。最终安装到手机上的apk其实就是只有宿主的apk和其内部的.so文件,通过加载.so文件来实现加载插件中的文件。热更新就是更新bundle.json文件和插件.so文件的过程。

增量更新?

增量更新的原理是:在服务器端先拿新版本安装包和旧版本安装包进行对比,在生成差异包之后下发,之后客户端根据对应的差异包和本地旧版本安装包合成,便生成了新版本安装包。

对于Small框架,它把每个插件都编译成.so文件,然后存放到app的native目录下,不过,如果它发现自己的download目录有新的插件,那么就会去加载download目录下的插件,并且这种加载优先权是最大的,也就是说它会优先加载download目录下的插件。所以,如果我们要做增量更新,旧文件就从app的native目录进行读取,然后从服务器端下载增量包,最后合成的文件存放到download目录下,这样每次插件启动都会到download目录下加载新的插件。

small android,Android-Small框架-基础相关推荐

  1. 《Android的设计与实现:卷I》——第2章 框架基础JNI

    第2章 框架基础JNI JNI(Java Native Interface,Java本地接口)是Java平台上定义的一套标准的本地编程接口.JNI允许Java代码与本地代码互操作,即Java代码可以调 ...

  2. 快速接入 Android BLE 开发的基础框架

    代码地址如下: http://www.demodashi.com/demo/12092.html * Android BLE基础操作框架,基于回调,操作简单.包含扫描.多连接.广播包解析.服务读写及通 ...

  3. 15类Android通用流行框架

    15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...

  4. Android接口和框架学习

    Android接口和框架学习 缩写: HAL:HardwareAbstraction Layer,硬件抽象层 CTS:CompatibilityTest Suite,兼容性测试套件 Android让你 ...

  5. android原生组件,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  6. Android常用ui,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  7. Android 常用开源框架源码解析 系列 (四)Glide

    一.定义  Glide 一个被google所推荐的图片加载库,作者是bumptech.对Android SDk 最低要求是 API 10  与之功能类似的是Square公司的picasso  二.基本 ...

  8. Android通用流行框架大全

    Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的磁盘缓存 2.图片加载 名称 描述 Android Universal Image Loade ...

  9. android炫酷叼ui,XUI: 一个简洁而优雅的Android原生UI框架,解放你的双手!

    XUI 一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView.Button.EditText.ImageView ...

  10. Android近场通信---NFC基础(一)

    Android近场通信---NFC基础(一) 本文介绍在Android系通过你所能执行的基本任务。它解释了如何用NDEF消息格式来发送和接收NFC数据,并且介绍了支持这些功能的Android框架API ...

最新文章

  1. 从SeekFree的Gitee开源库建立通用MM32开发模板
  2. python程序运行时间计算公式_Python执行时间的计算方法小结
  3. 第三次学JAVA再学不好就吃翔(part9)--基础语法之键盘录入
  4. 微软最强命令行工具 Windows Terminal,强势霸榜GitHub
  5. python自定义事件event的含义_python使用多线程与自定义event更新tinter的内容
  6. java aqs源码_java中AQS源码分析
  7. Redis秒杀功能设计与实现
  8. Nginx 与 Tomcat,Apache的区别
  9. unity2d 5.0游戏练习制作记录——2d 飞行射击游戏(一)
  10. 无线发射机中的正交上变频技术--USRP X410软件无线电平台开发
  11. 达芬奇调色软件:DaVinci Resolve Studio 16 Mac
  12. 使用 Premiere 制作视频简介
  13. 计算机格式化后,电脑格式化后需要重装系统吗_格式化电脑重装系统的方法步骤...
  14. python爬取裁判文书_使用selenium爬取裁判文书网
  15. 幼儿园进行计算机培训心得体会,幼儿园家园共育的开展感受和体会
  16. 输入出租车类型和里程,计算打车的费用。
  17. 使用不同的命令去打包正式,测试,本地vue项目
  18. GitHub 优秀的开源项目学习
  19. matlab从大到小排序的语句,从小到大排序的方法
  20. php的和谐脏话,大司马仅有的两次说脏话,听完网友笑出声,直播效果一片和谐!...

热门文章

  1. 2022-01-23
  2. SEO -- 搜索引擎优化
  3. 怎么用c语言画出坐标曲线,c语言打印贝塞尔曲线坐标(三阶)
  4. linux route命令删除多余路由
  5. 【网络安全】如何使用keimpx检测网络环境中的有效凭证
  6. 【Grafana】函数
  7. 5、MySQL修改数据库:ALTER DATABASE用法简介
  8. 京东每日特价专栏仿写
  9. 135. 最大子序和【前缀和 单调队列】
  10. 全文索引的使用(MySQL)