日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

SDK穩健接入

本文介紹移動熱修復SDK穩健接入的方法。

前提條件

使用限制

  • 支持Android 4.3及以上系統,如自研設備和系統,請關閉系統級jit后進行接入。

  • 如需要混淆,需要使用ProGuard進行混淆。

  • 熱修復SDK僅支持Java代碼、資源文件和so文件的修復。

集成步驟

  1. 添加工程依賴

    1. Android Studio集成方式

      gradle遠程倉庫依賴, 打開項目找到App的build.gradle文件,添加如下配置:

      添加Maven倉庫地址:

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

      添加gradle坐標版本依賴:

      android {
          ......
          defaultConfig {
              applicationId "com.xxx.xxx" //包名
              ......
              ndk {
                  //選擇要添加的對應cpu類型的.so庫。
                  //熱修復支持五種
                  abiFilters 'arm64-v8a', 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
              }
              ......
          }
          ......
      }
      dependencies {
          ......
              compile 'com.aliyun.ams:alicloud-android-hotfix:3.4.1'
          ......
      }

      如若倉庫訪問失敗, 那么用本地依賴的方式進行依賴。

      重要
      • 使用android studio打包生成apk時,要關閉instant run。

      • 使用gradle plugin版本高于4.2時,可能會因為自動開啟資源優化導致資源名稱被混淆,進而導致在生成補丁時一直卡在“開始構建補丁...”,無法正常解析apk包。解決方案:在gradle.properties 中新增android.enableResourceOptimizations=false,重新生成基線包和修復包,然后再生成補丁。

      • 如果開啟了代碼混淆,需要關閉R8,不然會導致生成的補丁較大。解決方案:在gradle.properties 中新增android.enableR8=false,重新生成基線包和修復包,然后再生成補丁。

      • 若SDK集成過程中出現UTDID沖突,請參考阿里云-云產品SDK UTDID沖突解決方案

    2. eclipse集成方式

      1. 下載OneSDk.zip,解壓后打開到libs目錄,libs目錄中,所有aar和jar文件都需要進行依賴。

      2. aar文件依賴方式:解壓aar文件,復制解壓文件jni目錄下的so文件到自己的jni目錄下, eclipse jni目錄一般指的就是項目libs目錄;復制jar文件項目libs目錄下。合并AndroidManifest.xml文件中的內容到本項目AndroidManifest.xml文件。

      3. 復制所有jar文件到項目libs目錄下。

      重要

      編譯期間報UTDID類重復異常, 請參考阿里云-云產品SDK UTDID沖突解決方案

  2. 添加應用權限

    Sophix SDK使用到以下權限,使用Maven依賴或者aar依賴可以不用配置。具體配置在AndroidManifest.xml中。

    <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" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    SDK權限

    是否必須

    說明

    INTERNET

    允許網絡請求,下載補丁時使用。

    ACCESS_NETWORK_STATE

    獲取運營商和網絡類型信息,用于統計不同網絡下的補丁加載狀態統計。

    ACCESS_WIFI_STATE

    獲取運營商和網絡類型信息,用于統計不同網絡下的補丁加載狀態統計。

    READ_EXTERNAL_STORAGE

    外部存儲讀權限,調試工具從SD卡加載本地補丁需要。

    說明

    READ_EXTERNAL_STORAGE權限屬于Dangerous Permissions,僅調試工具獲取外部補丁需要,不影響線上發布的補丁加載,調試時請自行做好Android 6.0以上的運行時權限獲取。

  3. 配置AndroidManifest文件

    AndroidManifest.xml中間的application節點下添加如下配置:

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

    將上述value中的值分別改為通過平臺HotFix服務申請得到的App Secret和RSA密鑰。App Secret和RSA密鑰的獲取方式請參見下載配置文件。出于安全考慮,建議使用setSecretMetaData這個方法進行設置,詳見SDK API的方法說明。如找不到對應參數,可參考EMAS速入門中的“下載SDK”獲取應用配置信息。

    說明

    • 另外,熱修復暫不支持EMAS統一插件的JSON文件讀取。

    • IDSECRET、APPSECRET、RSASECRET將被用于計量計費,請妥善保管注意安全。

    • 為避免在日志中泄露IDSECRET、APPSECRET、RSASECRET參數或APP運行過程中產生的數據,建議線上版本關閉SDK調試日志。

    • 由于所有用戶使用統一提供的SDK接入,在接入過程中需要在代碼中設置IDSECRET、APPSECRET、RSASECRET參數,為防止惡意反編譯獲取參數造成信息泄露,建議開啟混淆后再發布上線。

  4. 混淆配置

    #基線包使用,生成mapping.txt
    -printmapping mapping.txt
    #生成的mapping.txt在app/build/outputs/mapping/release路徑下,移動到/app路徑下
    #修復后的項目使用,保證混淆結果一致
    #-applymapping mapping.txt
    #hotfix
    -keep class com.taobao.sophix.**{*;}
    -keep class com.ta.utdid2.device.**{*;}
    #防止inline
    -dontoptimize
    重要

    開啟混淆時,生成修復包要使用舊包的mapping文件以保證混淆結果一致。

  5. 使用proguad混淆

    如果開啟了代碼混淆,需要關閉R8,使用proguard進行混淆。不然可能導致生成補丁異常。根據使用的Android Gradle Plugin版本,具體操作如下:

    1. Android Gradle Plugin低于7.0

      在項目根目錄的gradle.properties中添加如下配置。

      android.enableR8=false
    2. Android Gradle Plugin 7.0以上

      1. 在項目根目錄的build.gradle中添加如下ProGuard Gradle Plugin配置。

        buildscript {
            repositories {
                // For the Android Gradle plugin.
                google()
                // For the ProGuard Gradle Plugin.
                mavenCentral()
            }
            dependencies {
                // The Android Gradle plugin.
                classpath("com.android.tools.build:gradle:x.y.z")
                // The ProGuard Gradle plugin.
                classpath("com.guardsquare:proguard-gradle:7.1.+")
            }
        }
      2. 在app目錄的build.gradle中應用ProGuard Gradle Plugin。

        apply plugin: 'com.guardsquare.proguard'
      3. 然后,關閉R8混淆。

        android {
           buildTypes {
               release {
                   // 關閉 R8.
                   minifyEnabled false
               }
           }
        }
      4. 最后,配置ProGuard混淆。

        android {
           ...
        }
        
        proguard {
           configurations {
               release {
                   defaultConfiguration 'proguard-android.txt'
                   configuration 'proguard-rules.pro'
               }
               debug {
                   defaultConfiguration 'proguard-android-debug.txt'
                   configuration 'proguard-rules.pro'
               }
           }
        }
  6. 初始化

    初始化的調用應該盡可能的早,必須在Application.attachBaseContext()的最開始(在super.attachBaseContext之后,如果有Multidex,也需要在Multidex.install之后)進行SDK初始化操作,初始化之前不能用到其他自定義類,否則極有可能導致崩潰。而查詢服務器是否有可用補丁的操作可以在后面的任意地方。不建議在Application.onCreate()中初始化,因為如果帶有ContentProvider,就會使得Sophix初始化時機太遲從而引發問題。

    Sophix最新版本引入了新的初始化方式。

    原來的初始化方式仍然可以使用。只是新方式可以提供更全面的功能修復支持,將會帶來以下優點:

    • 初始化與應用原先業務代碼完全隔離,使得原先真正的Application可以修復,并且減少了補丁預加載時間等等。

    • 新方式能夠更完美地兼容Android 8.0以后版本。

    具體而言,是需要用戶自行加入以下這個類:

    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入口類,專門用于初始化Sophix,不應包含任何業務邏輯。
     * 此類必須繼承自SophixApplication,onCreate方法不需要實現。
     * 此類不應與項目中的其他類有任何互相調用的邏輯,必須完全做到隔離。
     * AndroidManifest中設置application為此類,而SophixEntry中設為原先Application類。
     * 注意原先Application里不需要再重復初始化Sophix,并且需要避免混淆原先Application類。
     * 如有其它自定義改造,請咨詢官方后妥善處理。
     */
    public class SophixStubApplication extends SophixApplication {
        private final String TAG = "SophixStubApplication";
        // 此處SophixEntry應指定真正的Application,并且保證RealApplicationStub類名不被混淆。
        @Keep
        @SophixEntry(MyRealApplication.class)
        static class RealApplicationStub {}
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
    //         如果需要使用MultiDex,需要在此處調用。
    //         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)
                    .setUsingEnhance(true) // 適配加固模式,如果app使用了加固則需要加上此方法
                    .setAppVersion(appVersion)
                    .setSecretMetaData(null, null, null)
                    .setEnableDebug(true)
                    .setEnableFullLog()
                    .setTags(Arrays.asList("Gray")) //請根據需求設置tag
                    .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) {
                                // 如果需要在后臺重啟,建議此處用SharePreference保存狀態。
                                Log.i(TAG, "sophix preload patch success. restart app to make effect.");
                            }
                        }
                    }).initialize();
        }
    }

    這其中,關鍵一點是:

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

    SophixEntry應指定項目中原先真正的Application(原項目里application的android::name指定的),這里用MyRealApplication指代。并且保證RealApplicationStub類名不被混淆。而SophixStubApplication的類名和包名可以自行取名。

    這里的Keep是android.support包中的類,目的是為了防止這個內部靜態類的類名被混淆,因為sophix內部會反射獲取這個類的SophixEntry。如果項目中沒有依賴android.support的話,就需要在progurad里面手動指定RealApplicationStub不被混淆,詳見下文。

    然后,在proguard文件里面需要加上下面內容:

    -keepclassmembers class com.my.pkg.MyRealApplication {
        public <init>();
    }
    -keep class com.my.pkg.SophixStubApplication$RealApplicationStub

    目的是防止真正Application的構造方法被proguard混淆。

    最后,需要把AndroidManifest里面的application改為這個新增的SophixStubApplication類:

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

    這樣便完成了新方式的初始化接入改造。

  7. 拉取補丁

    初始化完成之后,可以去服務端查詢并拉取補丁。

    SophixManager.getInstance().queryAndLoadNewPatch();
    重要
    • queryAndLoadNewPatch方法用來請求控制臺發布的補丁包,會發起網絡請求,所以必須在用戶同意隱私協議之后調用。

    • 但不可放在attachBaseContext中,否則無網絡權限,建議放在主進程用戶同意隱私協議之后的任意時刻。

遇到集成問題可先查看常見問題解決,通過文檔不能解決,可以聯系:聯系我們

學習資料參考

說明

如有其他非官方資料請通過聯系我們加釘釘群,把您的文章與我們分享,我們會挑選好文放在這里。