轻量级插件化框架——Small

photo-1441716844725-09cedc13a4e7.jpg

前言

Small官网: https://github.com/wequick/Small

世界那么大,组件那么小。Small,做最轻巧的跨平台插件化框架。 ——Galenlin

这是Small作者,林光亮老师,给Small一句概括。

今年6月份,我和同事Simon奔赴北京参加 GMTC全球移动技术大会2016。当时Galenlin给大家介绍了Small插件化框架,插件化加载dex、资源拆分、hook.....

Dynamic-load-apk的作者任玉刚也有演讲,不过没介绍DLA。

回广州后,对Small做了几个实验性demo,不禁赞叹Small真的非常简洁,而且基本能满足 APP组件化需求。


Small完成什么使命?

组件化,既熟悉又陌生的词汇。通俗点说,就是把APP拆分成不同功能模块,形成独立组件,让宿主调用。

组件化不一定是插件化,组件化是一个更大的概念:把模块解耦,组件之间代码不依赖,宿主可以依赖组件;而插件化则具体到了技术点上,宿主通过 动态加载 来调用组件,宿主不依赖组件,达到 完全解耦 的目的。

Small插件化方案适用于将一个APK拆分为多个公共库插件、业务模块插件的场景。

(知乎上一个插件化提问《怎么将 Android 程序做成插件化的形式?》

框架对比

Android插件化框架有很多,相信Dynamic-load-apk、ACDD、DroidPlugin 如雷贯耳。

Small官方比较:COMPARISION.md

  DyLA  : Dynamic-load-apk          @singwhatiwanna, 百度
  DiLA  : Direct-Load-apk           @FinalLody
  APF   : Android-Plugin-Framework  @limpoxe
  ACDD  : ACDD                      @bunnyblue
  DyAPK : DynamicAPK                @TediWang, 携程
  DPG   : DroidPlugin               @cmzy, 360
  • 功能
/ DyLA DiLA ACDD DyAPK DPG APF Small
加载非独立插件[1] × x ×
加载.so后缀插件 × × ! [2] × × ×
Activity生命周期
Service动态注册 × × × x [3]
资源分包共享[4] × × ! [5] ! [5] × ! [6]
公共插件打包共享[7] × × × × × ×
支持AppCompat[8] × × × × × ×
支持本地网页组件 × × × × × ×
支持联调插件[9] × x × × × ×

Small初体验

1.Create Project

假设宿主包名为com.example.mysmall

  1. 设置Application nameMySmall
  2. 修改Company Domainmysmall.example.com
create project.png

2.配置build.gradle

对project/build.gradle修改如下:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'

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

apply plugin: 'net.wequick.small'

small {
    aarVersion = '1.1.0-beta1'
}

...

com.android.tools.build:gradle用回你Android Studio支持的gradle插件版本)

aarVersionnet.wequick.tools.build:gradle-small版本号,可以参照Small官方sample的build.gradlesample

3.新建Application

new SmallApp

public class SmallApp extends Application {
  @Override
  public void onCreate() {
    super.onCreate();

    Small.preSetUp(this);
    
    Small.setBaseUri("http://example.com/");// 浏览器跳转url
    Small.setUp(this, null);
    // Small.setUp(this, new Small.OnCompleteListener(){...});
  }
}

AndroidManifest.xml:

<application
        android:name=".SmallApp"
        ...
        >

4.新建 插件Module

File->New->Module,选择Phone & Tablet Module

  • Application Name: App.main
  • Module name: app.main
  • package name: com.example.mysmall.app.main

如果选择Android Libraryapp.*换成lib.*

new module app.main.png

Small要求插件module满足:

  • 模块名形如:app.* , lib.* 或者web.*
  • 包名包含:.app., .lib.或者.web.

Add an Activity to Mobile选择最简单的Empty Activity即可(其他也可以)。

除了默认MainActivity,顺手创建多个ActivityB吧。

5.配置UI route

新建assets/bundle.json

{
    "version": "1.0.0",
    "bundles": [
        {
            "uri": "main",
            "pkg": "com.example.mysmall.app.main",
            "rules": {
                "page2": ".ActivityB"
            }
        }
    ]
}
  • uri : 跳转Activity需要的uri
  • pkg : 插件模块包名
  • rules : 指定跳转的Activity

Small/UI-route

6.跳转到插件Activity

  @Override
  public void onClick(View view) {
    Small.openUri("main", this); // open bundles.main Launch Activity
    // Small.openUri("main/page2", context);// 指定跳转到app.main.page2
  }

调用openUri后,就可以跳转到插件的某个Activity了。

7.编译插件

1)Build libraries (准备基础库)

gradlew buildLib

buildLib_appmain.gif

如果插件module是Android Library,这时会生成app/smallLibs/armeabi/*.so

2)Build bundles (打包所有组件)

gradlew buildBundle

buildBundle_appmain.gif

生成app/smallLibs/armeabi/libcom_example_mysmall_app_main.so

so文件.png

运行

由于project有两个Phone & Tablet Module,运行时要选app

5 - run config.png

使用效果

你会发现,宿主app没有依赖app.main,仅仅把app.main编译成so文件, 宿主app就可以跳转到插件app.main页面了。这就是插件化的魅力——零依赖


遇到的问题

之前遇到一个很奇葩的问题,如图:

some error

解决方法:

  • gradlew cleanLib
  • bradlew cleanBundle
  • 重新buildLib、buildBundle即可

还试过运行时提示“找不到app/MainActivity”,解决:File->Invalidate Caches/Restart清一下缓存再重启AS就好了。


小结

Small算是最简单的插件化框架,如果你的project本来就已经组件化到一定程度,使用Small轻而易举。

由于笔者还未试过在实际项目中使用,可能有些潜在的坑未踩。Small的更新也是蛮积极的,目前大概一个月更新一次,在交流Q群&issue,Galenlin回应也很积极。

强烈建议大家看看Small Issue,了解大家在使用中遇到的问题,以及Galenlin和其他人提出的解决方案。目前就4页,中文的,不会太多哈哈。

笔者相信,未来半年一年,Small会更稳定、更容易在项目中集成,让我们更爽地体验插件化的优势!

Small Demo Git


推荐阅读:

携程Android App插件化和动态加载实践
Android插件化:从入门到放弃


关于转载

如果你想转载此文,请务必在转载时,加上原文作者&原文链接。谢谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,653评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,321评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,833评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,472评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,306评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,274评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,658评论 3 385
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,335评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,638评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,697评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,454评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,311评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,699评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,986评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,254评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,647评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,847评论 2 335

推荐阅读更多精彩内容