Atlas接入及使用教程

Atlas指南

Atlas簡介

一洼哎、遠程Bundle:Bundle類似于Android項目中的Module的概念噩峦,遠程Bundle是項目編譯時不會打包進APK的模塊族淮,在項目編譯時祝辣,Atlas框架會將遠程Bundle生成一個.so文件蝙斜,我們將這個.so文件置于服務(wù)器孕荠,用戶使用APP時如果需要打開這個模塊岛琼,就從服務(wù)器上下載這個.so文件槐瑞,并加載到應(yīng)用中困檩,以此來減小安裝包的體積。

二等舔、熱更新:就是打補丁包,對一個版本進行代碼修改后义郑,可以通過Atlas框架根據(jù)修改的代碼生成差量補丁包非驮,客戶端可以通過下載服務(wù)器上的補丁包并部署劫笙,在不需要用戶更新應(yīng)用的情況下完成更新填大。

Atlas接入

參考:

手把手教你接入啊里的Atlas

Atlas官方指引

開源Android容器化框架Atlas開發(fā)者指南

1.新建項目

新建項目后施逾,再新建幾個 類型的Module(Bundle):

app

主工程

LibraryBundle

所有的項目依賴都在這個Bundle完成(比如Retrofit)汉额,其他的Bundle再依賴于這個Bundle

LocalBundle

本地Bundle蠕搜,在打包時就會打包到APK中

RemoteBundle

遠程Bundle妓灌,編譯后會生成.so文件虫埂,當(dāng)用戶需要打開某個模塊時掉伏,從服務(wù)器上下載這個.so文件供常,并加載到應(yīng)用中

01.PNG

2.修改Gradle

以下內(nèi)容基于 Android Studio3.0 栈暇,初始Gradle版本 4.1源祈, compileSdkVersion 26

這個步驟將會修改Gradle版本及compiledSdkVersion

修改Gradle版本至3.3

將工程目錄下的 gradle\wrapper\gradle-wrapper.properties 文件中的最后一行的值改成

https\://services.gradle.org/distributions/gradle-3.3-all.zip

這時Gradle報了一個錯: Gradle DSL method not found: 'google()'

可以將項目目錄下的build.gradle文件中兩個google()去掉,點及Try Again

Gradle又報了一個Minimum support Gradle version is 4.1. Current version is 3.3的錯脚草,這是因為剛剛我們修改的那個文件中的dependencies閉包中的classpath聲明的gradle版本不對

03.PNG

本來應(yīng)該是2.3.3版本,這里直接將classpath這一行替換

classpath "com.taobao.android:atlasplugin:2.3.3.rc12"

引入阿里的依賴(需要將原來的刪除)写隶,阿里依賴里面默認是2.1版本的Gradle

順便在這個文件中加入mavenLocal()如圖示

001.PNG

點擊Try Again之后Gradle又報了一個Could not find method implementation() ..............啥的錯...

這是因為之前建項目的時候是4.1版本的Gradle,它把項目的依賴從compile改成了implementation....

05.PNG

我們這時候?qū)odule下的build.gradle文件中的implementation改成compile

改完之后dependencies成了這樣:

06.PNG

在示例中直接將compileSdkVersion改成25冕房,同時需要修改的還有buildToolsVersion耙册,修改成'25.0.2'详拙,targetSdkVersion也改成25

同時之前新建的Module也像上面這樣修改

注意:

Android Studio會提示更新Gradle版本到4.1饶辙,不要讓Android Studio更新脯爪,點擊Don't remind me for this project

3.引入Atlas框架

修改app下的build.gradle

group = 'com.gavynzhang.myatlastest'
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 "com.gavynzhang.myatlastest"
        minSdkVersion 19
        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(dir: 'libs', include: ['*.jar'])
    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'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
    testCompile 'junit:junit:4.12'

    //atlas的依賴
    compile('com.taobao.android:atlas_core:5.0.7.42@aar') {
        transitive = true
    }
    compile 'com.taobao.android:atlasupdate:1.1.4.11@aar'
    compile 'com.alibaba:fastjson:1.1.45.android@jar'

    //項目依賴
    compile project(':librarybundle')
    compile project(':localbundle')
    compile project(':remotebundle')
}

//加入以下配置
atlas {
    atlasEnabled true   //打開atlas
    tBuildConfig {
        // autoStartBundles = ['com.android.homebundle'] //自啟動bundle配置
        outOfApkBundles = ['remotebundle']      //遠程module,列表來的守屉,可填多個
        preLaunch = 'com.gavynzhang.myatlastest.AtlasLaunch' //AppApplication啟動之前調(diào)用拇泛,這個類下面放出代碼
    }
    patchConfigs {
        debug {
            createTPatch true
        }
    }
    buildTypes {
        debug {
            if (apVersion) {
                // 打差異補丁 gradlew assembleDebug -DapVersion=1.1.0 -DversionName=1.1.1
                // 對應(yīng)著本地maven倉庫地址 .m2/repository/com/gavynzhang/myatlastest/AP-debug/1.0.0/AP-debug-1.0.0.ap
                baseApDependency "com.gavynzhang.myatlastest: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 {
    // 指定倉庫位置
    repositories {
        mavenLocal()
    }
    publications {
        // 默認本地倉庫地址  用戶目錄/.m2/repository/
        maven(MavenPublication) {
            //讀取ap目錄上傳maven
            artifact "${project.buildDir}/outputs/apk/${project.name}-debug.ap"
            //生成本地maven目錄
            groupId group
            artifactId "AP-debug"
        }
    }
}

修改RemoteBundle和LocalBundle中的build.gradle

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')
        }
    }
}

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        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(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    //依賴lib中間bundle
    compile project(':librarybundle')
}

需要將其中的applicationId刪去

修改LibraryBundle中的build.gradle

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        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(dir: 'libs', include: ['*.jar'])
    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'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
    testCompile 'junit:junit:4.12'

    compile 'com.squareup.okhttp3:okhttp:3.9.0'     //在librarybundle中添加依賴

}

修改AndroidManifest.xml文件

LocalBundleRemoteBundle中的AndroidManifest.xml修改成如下形式:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.gavynzhang.localbundle">

    <application>
        <activity android:name=".LocalMainActivity">
        </activity>
    </application>

</manifest>

LibraryBundle中的AndroidManifest.xml中的application標簽刪去

增加MyApplication

public class MyApplication 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)) {

                    //遠程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, " 遠程bundle不存在耗跛,請確定 : "
                                + 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, " 遠程bundle 安裝失敗晋南," + e.getMessage()
                                , Toast.LENGTH_LONG).show();
                        e.printStackTrace();
                    }

                    activity.startActivities(new Intent[]{intent});

                }

                return intent;
            }
        });

    }
}

增加類AtlasLaucher

public class AtlasLauncher implements AtlasPreLauncher {
    @Override
    public void initBeforeAtlas(Context context) {

    }
}

Atlas使用

加載遠程Bundle

先在 項目/app目錄下執(zhí)行 ..\gradlew.bat clean assembleDebug负间,執(zhí)行完成之后遠程Bundle的.so文件將在app/build/outputs/remote-bundles-debug目錄下

將遠程Bundle的.so文件下載到/sdcard/Android/data/應(yīng)用包名/cache目錄政溃,然后通過

Intent intent = new Intent();
intent.setClassName(view.getContext(),"com.gavynzhang.remotebundle.RemoteActivity");
activity.startActivity(intent);

來啟動這個遠程Bundle

加載本地Bundle

使用以下代碼即可:

Intent intent = new Intent();
intent.setClassName(view.getContext(), "com.gavynzhang.localbundle.MainActivity");
startActivity(intent);

項目構(gòu)建及運行

打包APK

在項目中的APP目錄下使用..\gradlew.bat clean assembleDebug

安裝

上一個步驟完成之后,生成的apk文件會在app/build/outputs/apk目錄下空扎,使用adb install build/outputs/apk/app-debug.apk將APK安裝到手機上

動態(tài)修補(TPatch)

發(fā)布基線版本

在app目錄下執(zhí)行..\gradlew.bat clean assembleDebug命令,執(zhí)行完成之后再執(zhí)行..\gradlew.bat publish命令

此時將會生成app-debug.apk文件盘寡,在app/build/outputs/apk目錄下

使用adb install 命令將app-debug.apk安裝到虛擬機或測試機上

生成動態(tài)修補相關(guān)文件

在項目中進行一些想要的修改之后(不支持AndroidManifest.xml的修改), 在app的build.gradle文件中修改versionName為新的version(如將"1.0.0"修改成"1.0.1");

然后在app目錄下執(zhí)行

..\gradlew.bat clean assembleDebug -DapVersion=apVersion -DversionName=newVersion命令竿痰,其中apVersion為修改之前的versionName影涉,newVersion為修改之后的versionName规伐;

如 ..\gradlew.bat clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1

此時相關(guān)的文件將在app/build/outputs/tpatch-debug目錄中生成蟹倾,我們需要將其中的

patch-1.0.1@1.0.0.tpatchupdate.json放到服務(wù)器上(.tpatch文件名由修改前后的versionName決定)

加載到app中

將之前生成的.tpatch文件和update.json文件下載到/sdcard/Android/data/應(yīng)用包名/cache目錄下,并執(zhí)行如下代碼:(需要在子線程中運行)

File updateInfo = new File(getExternalCacheDir(), "update.json");
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);   //調(diào)用Atlas進行動態(tài)修補
} catch (Throwable e) {
    e.printStackTrace();
    showToast("更新失敗, " + e.getMessage());
}

Atlas單模塊部署

當(dāng)項目越來越大猖闪,每次調(diào)試都重新構(gòu)建整個項目會非常地慢鲜棠,在Atlas中,可以使用

..\gradlew.bat clean assemblePatchDebug 在不重新安裝APP的情況下進行快速地調(diào)試(在APP運行的情況下)

具體流程如下:

  1. 先啟動已經(jīng)安裝的app
  2. 在Android Studio的命令行中切換到需要調(diào)試的Bundle的目錄下培慌,如 cd firstbundle
  3. 執(zhí)行..\gradlew.bat clean assemblePatchDebug

執(zhí)行完成后就能夠看到app重啟豁陆,單模塊部署生效

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吵护,隨后出現(xiàn)的幾起案子盒音,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偎血,死亡現(xiàn)場離奇詭異帖渠,居然都是意外死亡狞甚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門砸西,熙熙樓的掌柜王于貴愁眉苦臉地迎上來离福,“玉大人絮识,你說我怎么就攤上這事挪圾》园福” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵绩卤,是天一觀的道長凛驮。 經(jīng)常有香客問我本姥,道長艰管,這世上最難降的妖魔是什么街图? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任篙悯,我火速辦了婚禮矮燎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘正什。我一直安慰自己渠驼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布祈秕。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唆缴。 梳的紋絲不亂的頭發(fā)上氮双,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天球匕,我揣著相機與錄音瞬痘,去河邊找鬼。 笑死邻邮,一個胖子當(dāng)著我的面吹牛竣况,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筒严,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼丹泉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鸭蛙?” 一聲冷哼從身側(cè)響起摹恨,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娶视,沒想到半個月后晒哄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡肪获,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年寝凌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孝赫。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡较木,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出青柄,到底是詐尸還是另有隱情伐债,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布致开,位于F島的核電站峰锁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏喇喉。R本人自食惡果不足惜祖今,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拣技。 院中可真熱鬧千诬,春花似錦、人聲如沸膏斤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莫辨。三九已至傲茄,卻和暖如春毅访,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盘榨。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工喻粹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人草巡。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓守呜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親山憨。 傳聞我的和親對象是個殘疾皇子查乒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,262評論 25 707
  • 1.介紹 如果你正在查閱build.gradle文件的所有可選項,請點擊這里進行查閱:DSL參考 1.1新構(gòu)建系統(tǒng)...
    Chuckiefan閱讀 12,142評論 8 72
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理郁竟,服務(wù)發(fā)現(xiàn)玛迄,斷路器,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 僅記錄集成Atlas的過程和遇到的問題與總結(jié)棚亩。 文檔書寫日期中atlas版本可能稍早蓖议,且atlas更新較快,不保證...
    草貌路飛閱讀 9,325評論 2 12
  • 今天讀了幾句很喜歡的話~ 一:無論走過多少日子蔑舞,有懂得拒担,有花香,有陽光便是幸福攻询。 二:無畏的時光/拾遺沒有量詞操縱...
    淡_淡閱讀 548評論 0 0