阿里最新熱修復(fù)框架sophix集成詳解(二):工程代碼快速接入

本文更新于2017年11月20日

  • studio添加依賴(lài):

gradle遠(yuǎn)程倉(cāng)庫(kù)依賴(lài), 打開(kāi)項(xiàng)目找到app的build.gradle文件,添加如下配置:
添加maven倉(cāng)庫(kù)地址:

repositories {
   maven {
   url "http://maven.aliyun.com/nexus/content/repositories/releases"
     }
  }

添加gradle坐標(biāo)版本依賴(lài):

compile 'com.aliyun.ams:alicloud-android-hotfix:3.1.6'
  • 配置AndroidManifest文件

    • 需要用到一下權(quán)限:

      <! -- 網(wǎng)絡(luò)權(quán)限 -->
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      <! -- 外部存儲(chǔ)讀權(quán)限切威,調(diào)試工具加載本地補(bǔ)丁需要 -->
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
      

      READ_EXTERNAL_STORAGE權(quán)限屬于Dangerous Permissions娜膘,僅調(diào)試工具獲取外部補(bǔ)丁需要惜辑,不影響線(xiàn)上發(fā)布的補(bǔ)丁加載涕刚,調(diào)試時(shí)請(qǐng)自行做好android6.0以上的運(yùn)行時(shí)權(quán)限獲取儡毕。

    • application節(jié)點(diǎn)下添加如下配置:添加AppId,AppSecret,RSA密鑰

      <meta-data
        android:name="com.taobao.android.hotfix.IDSECRET" android:value="AppId" />
      <meta-data
        android:name="com.taobao.android.hotfix.APPSECRET" android:value="AppSecret" />
      <meta-data
        android:name="com.taobao.android.hotfix.RSASECRET" android:value="RSA密鑰" />
      

      如何獲取AppId,AppSecret,RSA密鑰交排,不知道的請(qǐng)看我的sophix集成系列第一篇:阿里最新熱修復(fù)框架sophix集成詳解(一):控制臺(tái)開(kāi)通移動(dòng)熱修復(fù)

      因?yàn)锳ppSecret和RSA密鑰比較敏感划滋,出于安全考慮,可以在代碼中通過(guò)setSecretMetaData這個(gè)方法進(jìn)行設(shè)置埃篓。這個(gè)下面寫(xiě)Java代碼時(shí)再說(shuō)处坪。

  • 混淆配置

    #基線(xiàn)包使用,生成mapping.txt
    -printmapping mapping.txt
    #生成的mapping.txt在app/buidl/outputs/mapping/release路徑下,移動(dòng)到/app路徑下
    #修復(fù)后的項(xiàng)目使用同窘,保證混淆結(jié)果一致
    #-applymapping mapping.txt
    #hotfix
    -keep class com.taobao.sophix.**{*;}
    -keep class com.ta.utdid2.device.**{*;}
    #防止inline
    -dontoptimize
    
  • Java代碼初始化接入

Sophix 3.1.6版本以后引入了新的初始化方式玄帕。

原來(lái)的初始化方式仍然可以使用,不過(guò)新方式將會(huì)帶來(lái)以下優(yōu)點(diǎn):初始化與應(yīng)用原先業(yè)務(wù)代碼完全隔離想邦,使得原先真正的Application可以修復(fù)裤纹,并且減少了補(bǔ)丁預(yù)加載時(shí)間。而且丧没,新方式已經(jīng)優(yōu)先支持Android 8.0版本鹰椒。
本文使用這種新型方式。

1- 導(dǎo)入SophixStubApplication
需要加入這個(gè)類(lèi):

package com.my.pkg;
import android.app.Application;
import android.content.Context;
import android.support.annotation.Keep;
import android.util.Log;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixApplication;
import com.taobao.sophix.SophixEntry;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;
import com.my.pkg.MyRealApplication;
/**
 * Sophix入口類(lèi)骂铁,專(zhuān)門(mén)用于初始化Sophix吹零,不應(yīng)包含任何業(yè)務(wù)邏輯。
 * 此類(lèi)必須繼承自SophixApplication拉庵,onCreate方法不需要實(shí)現(xiàn)灿椅。
 * AndroidManifest中設(shè)置application為此類(lèi),而SophixEntry中設(shè)為原先Application類(lèi)钞支。
 * 注意原先Application里不需要再重復(fù)初始化Sophix茫蛹,并且需要避免混淆原先Application類(lèi)。
 * 如有其它自定義改造烁挟,請(qǐng)咨詢(xún)官方后妥善處理婴洼。
 */
public class SophixStubApplication extends SophixApplication {
    private final String TAG = "SophixStubApplication";
    // 此處SophixEntry應(yīng)指定真正的Application,也就是你的應(yīng)用中原有的主Application撼嗓,并且保證RealApplicationStub類(lèi)名不被混淆柬采。
    @Keep
    @SophixEntry(MyRealApplication.class)
    static class RealApplicationStub {}
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //         如果需要使用MultiDex,需要在此處調(diào)用且警。
        //         MultiDex.install(this);
        initSophix();
    }
    private void initSophix() {
        String appVersion = "0.0.0";
        try {
          appVersion = this.getPackageManager()
                         .getPackageInfo(this.getPackageName(), 0)
                         .versionName;
        } catch (Exception e) {
        }
        final SophixManager instance = SophixManager.getInstance();
    instance.setContext(this)
            .setAppVersion(appVersion)
            .setSecretMetaData(null, null, null) //三個(gè)參數(shù)分別對(duì)應(yīng)AndroidManifest里面的AppId粉捻、AppSecret、RSA密鑰斑芜,可以不在AndroidManifest設(shè)置而是用此函數(shù)來(lái)設(shè)置Secret肩刃。放到代碼里面進(jìn)行設(shè)置可以自定義混淆代碼,更加安全杏头,此函數(shù)的設(shè)置會(huì)覆蓋AndroidManifest里面的設(shè)置盈包,如果對(duì)應(yīng)的值設(shè)為null,默認(rèn)會(huì)在使用AndroidManifest里面的醇王。
            .setEnableDebug(true)//默認(rèn)為false呢燥,設(shè)為true即調(diào)試模式下會(huì)輸出日志以及不進(jìn)行補(bǔ)丁簽名校驗(yàn). 線(xiàn)下調(diào)試此參數(shù)可以設(shè)置為true, 它會(huì)強(qiáng)制不對(duì)補(bǔ)丁進(jìn)行簽名校驗(yàn), 所有就算補(bǔ)丁未簽名或者簽名失敗也發(fā)現(xiàn)可以加載成功. 但是正式發(fā)布該參數(shù)必須為false, false會(huì)對(duì)補(bǔ)丁做簽名校驗(yàn), 否則就可能存在安全漏洞風(fēng)險(xiǎn)。
            .setEnableFullLog()
            .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                @Override
                public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                    if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                        Log.i(TAG, "sophix load patch success!");
                    } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                        // 如果需要在后臺(tái)重啟寓娩,建議此處用SharePreference保存狀態(tài)叛氨。
                        Log.i(TAG, "sophix preload patch success. restart app to make effect.");
                        /** 不可以直接Process.killProcess(Process.myPid())來(lái)殺進(jìn)程滥朱,這樣會(huì)擾亂Sophix的內(nèi)部狀態(tài)。
                         * 因此如果需要?dú)⑺肋M(jìn)程力试,建議使用這個(gè)方法徙邻,它在內(nèi)部做一些適當(dāng)處理后才殺死本進(jìn)程。*/
                        instance.killProcessSafely();
                    }
                }
            }).initialize();
    }
    @Override
    public void onCreate() {
      super.onCreate();
      // queryAndLoadNewPatch不可放在attachBaseContext 中畸裳,否則無(wú)網(wǎng)絡(luò)權(quán)限缰犁,建議放在后面任意時(shí)刻,如onCreate中
      SophixManager.getInstance().queryAndLoadNewPatch();
      /** 補(bǔ)丁在后臺(tái)發(fā)布之后, 并不會(huì)主動(dòng)下行推送到客戶(hù)端, 客戶(hù)端通過(guò)調(diào)用queryAndLoadNewPatch方法查詢(xún)后臺(tái)補(bǔ)丁是否可用*/
    }
}

初始化sophix務(wù)必放在attachBaseContext中怖糊,onCreate不需要自行實(shí)現(xiàn)帅容。同時(shí)自定義的SophixStubApplication需要繼承com.taobao.sophix.SophixApplication。
這其中伍伤,關(guān)鍵一點(diǎn)是:

@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {}

SophixEntry應(yīng)指定項(xiàng)目中原先真正的Application(原項(xiàng)目里application的android::name指定的)并徘,這里用MyRealApplication指代。并且保證RealApplicationStub類(lèi)名不被混淆扰魂。而SophixStubApplication的類(lèi)名和包名可以自行取名麦乞。

這里的Keep是android.support包中的類(lèi),目的是為了防止這個(gè)內(nèi)部靜態(tài)類(lèi)的類(lèi)名被混淆劝评,因?yàn)閟ophix內(nèi)部會(huì)反射獲取這個(gè)類(lèi)的SophixEntry姐直。如果項(xiàng)目中沒(méi)有依賴(lài)android.support的話(huà),就需要在progurad里面手動(dòng)指定RealApplicationStub不被混淆蒋畜。

2- 然后声畏,在proguard文件里面需要加上下面內(nèi)容:

-keepclassmembers class com.my.pkg.MyRealApplication {
  public <init>();
}
# 如果不使用android.support.annotation.Keep則需加上此行
# -keep class com.my.pkg.SophixStubApplication$RealApplicationStub

目的是防止真正Application的構(gòu)造方法被proguard混淆。

最后姻成,需要把AndroidManifest里面的application改為這個(gè)新增的SophixStubApplication類(lèi):

 <application
    android:name="com.my.pkg.SophixStubApplication"
    ... ...>
    ... ...

sample源碼
下一篇插龄,阿里最新熱修復(fù)框架sophix集成詳解(三):生成、上傳科展、調(diào)試補(bǔ)丁

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末均牢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辛润,更是在濱河造成了極大的恐慌膨处,老刑警劉巖见秤,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砂竖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鹃答,警方通過(guò)查閱死者的電腦和手機(jī)乎澄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)测摔,“玉大人置济,你說(shuō)我怎么就攤上這事解恰。” “怎么了浙于?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵护盈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我羞酗,道長(zhǎng)腐宋,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任檀轨,我火速辦了婚禮胸竞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘参萄。我一直安慰自己卫枝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布讹挎。 她就那樣靜靜地躺著校赤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筒溃。 梳的紋絲不亂的頭發(fā)上痒谴,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音铡羡,去河邊找鬼积蔚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛烦周,可吹牛的內(nèi)容都是我干的尽爆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼读慎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼漱贱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起夭委,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤幅狮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后株灸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體崇摄,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年慌烧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逐抑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屹蚊,死狀恐怖厕氨,靈堂內(nèi)的尸體忽然破棺而出进每,到底是詐尸還是另有隱情,我是刑警寧澤命斧,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布田晚,位于F島的核電站,受9級(jí)特大地震影響国葬,放射性物質(zhì)發(fā)生泄漏肉瓦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一胃惜、第九天 我趴在偏房一處隱蔽的房頂上張望泞莉。 院中可真熱鬧,春花似錦船殉、人聲如沸鲫趁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挨厚。三九已至,卻和暖如春糠惫,著一層夾襖步出監(jiān)牢的瞬間疫剃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工硼讽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巢价,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓固阁,卻偏偏與公主長(zhǎng)得像壤躲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子备燃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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