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文件,當用戶需要打開某個模塊時,從服務(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單模塊部署

當項目越來越大,每次調(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容