前言
Atlas已經(jīng)出了很久,這幾天剛好有個(gè)空檔期研究了一下骑祟,在沒啥資料的情況下回懦,加了一堆群,踩了一堆坑次企,終于成功接入了怯晕。本文就是記錄接入的過程捅厂,并不會(huì)講解太多的原理租副,想要知道原理的前往:官網(wǎng)
主要功能
一、遠(yuǎn)程Bundle茬高,就是打包的時(shí)候不會(huì)把這個(gè)bundle打包進(jìn)去堵第,減少apk的安裝體積吧凉,用戶安裝apk后,需要加載那個(gè)功能的話踏志,就從網(wǎng)上下載這個(gè)bundle的so阀捅,然后加載打開,當(dāng)然下載邏輯是app寫的狰贯。適用模塊比較多的app使用也搓,按需加載模塊。
二涵紊、熱更新傍妒,就是出補(bǔ)丁包,對(duì)一個(gè)版本進(jìn)行代碼修改摸柄,在不需要用戶更新apk的情況下完成更新颤练。
開始接入
一、新建一個(gè)項(xiàng)目驱负,然后新建幾個(gè)module嗦玖,如下圖
二、配置
1跃脊、把gradle改為3.3
2宇挫、項(xiàng)目級(jí)的build
buildscript {
repositories {
jcenter()
mavenLocal()//本地maven
}
//引入啊里的依賴,不需要再依賴classpath "com.android.tools.build:gradle"的版本酪术,默認(rèn)使用的是 2.1
dependencies {
classpath "com.taobao.android:atlasplugin:2.3.1.rc9"
}
}
allprojects {
repositories {
jcenter()
mavenLocal()//本地maven
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
3器瘪、app的build
// 需要放最上面初始化
group = "mmc.atlastest"
version = getEnvValue("versionName", "1.0.0");
def apVersion = getEnvValue("apVersion", "");
apply plugin: 'com.android.application'
apply plugin: 'com.taobao.atlas'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "mmc.atlastest"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName version
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//atlas的依賴
compile('com.taobao.android:atlas_core:5.0.7@aar') {
transitive = true
}
compile 'com.taobao.android:atlasupdate:1.1.4.7@aar'
compile 'com.alibaba:fastjson:1.1.45.android@jar'
//項(xiàng)目依賴
compile project(':librarybundle')
compile project(':localbundle')
compile project(':remotebundle')
}
//加入以下配置
atlas {
atlasEnabled true
tBuildConfig {
// autoStartBundles = ['com.android.homebundle'] //自啟動(dòng)bundle配置
outOfApkBundles = ['remotebundle'] //遠(yuǎn)程module翠储,列表來的,可填多個(gè)
preLaunch = 'mmc.atlastest.AtlasLaunch' //AppApplication啟動(dòng)之前調(diào)用橡疼,這個(gè)類下面放出代碼
}
patchConfigs {
debug {
createTPatch true
}
}
buildTypes {
debug {
if (apVersion) {
// 打差異補(bǔ)丁 gradlew assembleDebug -DapVersion=1.1.0 -DversionName=1.1.1
// 對(duì)應(yīng)著本地maven倉(cāng)庫(kù)地址 .m2/repository/mmc/atlastest/AP-debug/1.1.4/AP-debug-1.1.4.ap
baseApDependency "mmc.atlastest:AP-debug:${apVersion}@ap"
patchConfig patchConfigs.debug
}
}
}
}
String getEnvValue(key, defValue) {
def val = System.getProperty(key);
if (null != val) {
return val;
}
val = System.getenv(key);
if (null != val) {
return val;
}
return defValue;
}
apply plugin: 'maven'
apply plugin: 'maven-publish'
publishing {
// 指定倉(cāng)庫(kù)位置
repositories {
mavenLocal()
}
publications {
// 默認(rèn)本地倉(cāng)庫(kù)地址 用戶目錄/.m2/repository/
maven(MavenPublication) {
//讀取ap目錄上傳maven
artifact "${project.buildDir}/outputs/apk/${project.name}-debug.ap"
//生成本地maven目錄
groupId group
artifactId "AP-debug"
}
}
}
4援所、遠(yuǎn)程bundle和本地bundle的build
apply plugin: 'com.android.library'
apply plugin: 'com.taobao.atlas'
atlas {
bundleConfig{
awbBundle true
}
buildTypes {
debug {
baseApFile project.rootProject.file('app/build/outputs/apk/app-debug.ap')
}
}
}
//只添加上面的配置就行了,下面的是默認(rèn)生成的
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//依賴lib中間bundle
compile project(':librarybundle')
}
5欣除、application里面添加
public class DemoApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Atlas.getInstance().setClassNotFoundInterceptorCallback(new ClassNotFoundInterceptorCallback() {
@Override
public Intent returnIntent(Intent intent) {
final String className = intent.getComponent().getClassName();
final String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);
if (!TextUtils.isEmpty(bundleName) && !AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {
//遠(yuǎn)程bundle
Activity activity = ActivityTaskMgr.getInstance().peekTopActivity();
File remoteBundleFile = new File(activity.getExternalCacheDir(),"lib" + bundleName.replace(".","_") + ".so");
String path = "";
if (remoteBundleFile.exists()){
path = remoteBundleFile.getAbsolutePath();
}else {
Toast.makeText(activity, " 遠(yuǎn)程bundle不存在住拭,請(qǐng)確定 : " + remoteBundleFile.getAbsolutePath() , Toast.LENGTH_LONG).show();
return intent;
}
PackageInfo info = activity.getPackageManager().getPackageArchiveInfo(path, 0);
try {
Atlas.getInstance().installBundle(info.packageName, new File(path));
} catch (BundleException e) {
Toast.makeText(activity, " 遠(yuǎn)程bundle 安裝失敗," + e.getMessage() , Toast.LENGTH_LONG).show();
e.printStackTrace();
}
activity.startActivities(new Intent[]{intent});
}
return intent;
}
});
}
}
6历帚、在app新建一個(gè)類AtlasLaunch滔岳,繼承AtlasPreLauncher
public class AtlasLaunch implements AtlasPreLauncher {
@Override
public void initBeforeAtlas(Context context) {
}
}
三、然后寫app的基本功能抹缕,示例如下圖:
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//打開遠(yuǎn)程bundle
public void remote(View view){
Intent intent = new Intent();
intent.setClassName(view.getContext(), "mmc.remotebundle.RemoteActivity");
startActivity(intent);
}
//打開本地bundle
public void local(View view){
Intent intent = new Intent();
intent.setClassName(view.getContext(), "mmc.localbundle.LocalActivity");
startActivity(intent);
}
//更新補(bǔ)丁
public void update(View view){
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
update();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(MainActivity.this, "更新完成澈蟆,請(qǐng)重啟", Toast.LENGTH_LONG).show();
}
}.execute();
}
private void update(){
File updateInfo = new File(getExternalCacheDir(), "update.json");
if (!updateInfo.exists()) {
showToast("更新信息不存在,請(qǐng)先 執(zhí)行 buildTpatch.sh");
return;
}
String jsonStr = new String(FileUtils.readFile(updateInfo));
UpdateInfo info = JSON.parseObject(jsonStr, UpdateInfo.class);
File patchFile = new File(getExternalCacheDir(), "patch-" + info.updateVersion + "@" + info.baseVersion + ".tpatch");
try {
AtlasUpdater.update(info, patchFile);
} catch (Throwable e) {
e.printStackTrace();
showToast("更新失敗, " + e.getMessage());
}
}
}
四卓研、安裝運(yùn)行這個(gè)版本的apk趴俘,界面如下:
1、這個(gè)時(shí)候點(diǎn)擊遠(yuǎn)程bundle會(huì)彈出說沒有so文件奏赘,因?yàn)檫€沒打so包呢
2寥闪、點(diǎn)擊本地bundle,是可以跳轉(zhuǎn)到那個(gè)本地bundle頁(yè)面
3磨淌、點(diǎn)擊更新補(bǔ)丁疲憋,會(huì)提示更新信息不存在
重點(diǎn)來了
下面要打包出遠(yuǎn)程bundle的so文件,補(bǔ)丁的差異包和更新說明
1梁只、打so文件缚柳,每個(gè)遠(yuǎn)程都會(huì)生成一個(gè)so文件的。打開AS的Terminal搪锣,輸入:gradlew clean assembleDebug publish
秋忙,然后回車,如下圖:
正常的話构舟,會(huì)提示這個(gè):
如果提示下面這個(gè)錯(cuò)
那就把java進(jìn)程全部殺掉灰追,然后重試,原因是為啥狗超,我也不知道
成功的話弹澎,app的build文件夾里,會(huì)生成這個(gè)so文件努咐,這個(gè)就是遠(yuǎn)程bundle的so文件苦蒿,把這個(gè)文件放到手機(jī)內(nèi)存卡Android/data/mmc.atlastest/cache 文件夾里面,然后再打開app渗稍,點(diǎn)擊“遠(yuǎn)程Bundle”刽肠,這個(gè)時(shí)候就能跳轉(zhuǎn)過去了溃肪。
2免胃、更新補(bǔ)丁音五,打差異包和更新說明
接著第一步,然后修改版本號(hào)羔沙,對(duì)本地Bundle進(jìn)行文字修改躺涝,對(duì)app主項(xiàng)目也可以修改(修改已有的Activity)
修改后,在Terminal里面輸入:gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1
回車扼雏,成功后會(huì)生成補(bǔ)丁差異包和更新說明坚嗜,如下圖:
把紅色圈中的兩個(gè)文件,放到手機(jī)內(nèi)存卡Android/data/mmc.atlastest/cache 文件夾里面诗充,然后點(diǎn)擊“更新補(bǔ)丁”苍蔬,過一會(huì),提示更新成功后蝴蜓,就退出殺死app碟绑,再打開就是后面修改的內(nèi)容了。
這樣就完成更新過程了茎匠,完整源碼:AtlasTest
總結(jié)步驟
1格仲、配置好,安裝1.0.0的app
2诵冒、用命令“gradlew clean assembleDebug publish”打AP凯肋,得到遠(yuǎn)程Bundle的so文件
3、修改版本號(hào)汽馋,修改版本內(nèi)容
4侮东、用命令“gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1”打差異包補(bǔ)丁和更新說明
5、把上面得到的三個(gè)文件放到app的cache目錄里面
6豹芯、運(yùn)行更新方法悄雅,殺死app,重啟