android small通信,使用Small进行Android模块化开发

本文详细介绍了如何使用Android的Small框架进行插件化开发,包括Small的初始化、插件编译、运行过程分析及热更新实现。文章强调了在工程结构、资源管理和签名配置等方面的最佳实践,并提供了遇到问题时的解决策略。此外,还探讨了如何通过uri启动插件Activity以及处理AndroidManifest的相关事项。
摘要由CSDN通过智能技术生成

如果你还未尝试过Small,建议你可以先去github上看看怎么使用Small 。

由于github上的文档较少,而且项目还在发展阶段,所以关于怎么使用Small的线索只能从Issue中寻找线索,而且有些问题是历史版本的问题。

这篇文章主要讲几个实践中的经验,也欢迎大家反馈使用中遇到的问题,一起踩坑。

根目录build.gradle

使用Small架构的工程中,根目录的build.gradle中一定包含

buildscript {

dependencies {

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

}

}

apply plugin: 'net.wequick.small'

small {

aarVersion = '1.1.0-beta9'

}

classpath是指定编译时类的依赖关系

aarVersion是指定运行时使用的small依赖包版本号

对于相同的版本号alpha > beta

版本号的历史记录可以在Bintray上看到

工程目录结构

cd152c75b0e0

small_framework.png

上图是一个建议的工程结构图,一个Android Studio工程中包含三大部分

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

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

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

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

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

以上方案只是一个建议,还是要根据项目的特点划分lib.xxx

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

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

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

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

{

"version": "1.0.0",

"bundles": [

{

"uri": "main",

"pkg": "com.example.mysmall.app.main",

"rules":{

"community":".CommunityFragment"

}

},

{

"uri": "lib.main",

"pkg": "com.example.mysmall.lib.main"

}

]

}

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

这里注意,lib模块也要在bundle中定义,否则运行时会出错。

还需要在宿主模块中增加签名配置和共享的依赖库

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'

关于怎么添加一个插件模块,请参考怎么使用Small

编译

编译公共库插件

[./]gradlew buildLib -q (-q是安静模式,可以让输出更好看,也可以不加)

cd152c75b0e0

small_build_lib.gif

可以看到buildLib不仅编译了lib.xxx,还编译了宿主模块。

编译业务插件

[./]gradlew buildBundle -q

cd152c75b0e0

small_build_bundle.gif

单独编译一个插件

[./]gradlew -p app.main assembleRelease

对插件的编译,会在app/smallLibs/生成对应的so文件,这些so文件本质上就是独立的apk包。

所以修改某个模块之后,要在运行时生效,必须先编译对应的插件,更新smallLibs下的so文件。

在lib.xxx中删除资源

编译后的lib,如果删除资源再编译就会出现错误

No support deleting resources on lib.* now!

这是为了保证lib的资源id不变,从而可以独立更新而不影响任何依赖它的app插件。具体可参考为什么要使用last built id

所以在删除lib中的资源后,需要删除lib.xxx模块下的public.txt再通过cleanLib, buildLib, cleanBundle, buildBundle重新编译。

运行过程分析

Small的运行可以分为三步

框架的初始化

插件的初始化

通过uri启动插件

public class SmallApplication extends Application {

@Override

public void onCreate() {

super.onCreate();

CrashHandler.getInstance().setCustomCrashHanler(getApplicationContext());

/**

* 1. Small框架初始化

*/

Small.preSetUp(this);

}

}

public class SplashActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_splash);

/**

* 2. Small插件初始化

*/

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

@Override

public void onComplete() {

/**

* 3. 通过uri启动插件

*/

Small.openUri("main", SplashActivity.this)

finish();

}

});

}

}

从插件初始化,到初始化完成会耗费几百毫秒,甚至更多(应该和机器速度和插件规模相关),所以可以考虑将欢迎页放入宿主工程之中。

如果欢迎页有比较复杂的广告逻辑或统计相关的逻辑,则可以考虑在主插件中做一个透明的Activity来处理。

Manifest相关

application:可以在插件的Manifest中指定application,每个插件的Application都会在Small.setup时被创建

android:configChanges:由于android:configChanges属性暂未支持,因此对于需要处理android:configChanges的Activity需要在宿主中注册(由于宿主工程和插件工程在编译时是互相隔离的,所以这些定义在宿主中的插件activty需要指定style)

activity:如果要通过uri启动Activity,则对应Activity应该在app.xxx插件的Manifest中进行注册。否则在通过uri启动时会出错。如果需app插件可以独立运行,但在Manifest中至少要注册一个主Activity。

热更新

插件so默认会内置在apk中,如果不内置也可以在启动页下载插件

热更新就是更新bundle.json和插件so的过程,为了避免热更新的异常,可以下载bundle先保存到一个临时目录,全下载完之后,统一复制到patch目录下,并标记升级。

通过接口获取更新信息,里面可以包括version,bundles,updates

{

"manifest": {

"version": "1.0.0",

"bundles": [

{

"uri": "lib.utils",

"pkg": "net.wequick.example.small.lib.utils"

},

{

"uri": "lib.style",

"pkg": "com.example.mysmall.lib.style"

},

{

"uri": "lib.analytics",

"pkg": "net.wequick.example.lib.analytics"

},

{

"uri": "main",

"pkg": "net.wequick.example.small.app.main"

},

{

"uri": "home",

"pkg": "net.wequick.example.small.app.home"

},

{

"uri": "mine",

"pkg": "net.wequick.example.small.app.mine"

},

{

"uri": "detail",

"pkg": "net.wequick.example.small.app.detail",

"rules": {

"sub": "Sub"

}

},

{

"uri": "about",

"pkg": "net.wequick.example.small.app.about"

}

]

},

"updates": [

{

"pkg": "net.wequick.example.small.app.about",

"url": "http://wequick.github.io/small/upgrade/libnet_wequick_example_small_app_about.so"

},

{

"pkg": "net.wequick.example.small.lib.utils",

"url": "http://wequick.github.io/small/upgrade/libnet_wequick_example_small_lib_utils.so"

},

{

"pkg": "com.example.mysmall.lib.style",

"url": "http://wequick.github.io/small/upgrade/libcom_example_mysmall_lib_style.so"

},

{

"pkg": "net.wequick.example.small.app.home",

"url": "http://wequick.github.io/small/upgrade/libnet_wequick_example_small_app_home.so"

}

]

}

2. 通过**Small.updateManifest**更新bundles.json和version信息

3. 根据updates下载各插件的so文件,并将so文件复制到对应的补丁文件路径下(通过**Bundle.getPatchFile**获取补丁文件目录)

4. 调用**Bundle.upgrade**使更新后的插件生效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值