small android,Android-Small框架-基础
簡介
插件模塊是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框架-基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 伪mac android,Mac,and
- 下一篇: 电脑其他设备android打问号,电脑设