Andriod 多渠道分包,實用的module分層,開發代碼混淆規

Andriod 多渠道分包,實用的module分層,開發代碼混淆規則

Andriod studio 3.0 有必要重新學習更好的處理build.gradle 看了很多文章到這裏來總結下:


多渠道打包

  • 多渠道打包

    Andriod studio3.0 build apk 多了一個 build apk(S)
    build apk(S)

    這個會直接生成 apk debug版

    將 apk 放入jdk的安裝目錄bin 文件下

    如果返回以驗證 就說明apk 已經簽名了
    cmd

    不過我感覺不實用了 大家還是用代碼跑吧。

進入正題

我們需要用到分渠道打包,那麼我們需要解決兩個問題
1. 怎麼區分各個平臺的標識
2. 怎麼每次版本更新都生成幾十個包、幾百個包

第一步

在AndroidManifext.xml中配置:
<meta-data
        android:name="UMENG_CHANNEL"
        android:value="${UMENG_CHANNEL_VALUE}" />

value裏面填的就是各個平臺的值,比如填寫uc、yyb(應用寶)、360、baidu替換掉Channel_ID,App安裝好,可以讀取這個值然後傳給後臺,從而實現區分各個平臺的安裝需求。

第二步

配置我們的 app/build.gradle

我們需要配置:

1 signingConfigs這是剛纔我們新建的密匙信息
2 buildTypes 打包類型,包括了Debug和Release
3 productFlavors打包渠道就在這兒配置咯 同時在AndroidManifest裏面加上,渠道標識

apply plugin: 'com.android.application'



android {
//    關閉 multi-APK
//
//    multi-apk 是爲了根據配置生成不同的APK,以達到減少APK體積大小的問題。但是這個配置沒有必要在開發的時候開啓。
    if(project.hasProperty('devBuild')){
        splits.abi.enable = false
        splits.density.enable = false
        aaptOptions.cruncherEnabled = false
    }

    //簽名密鑰
    signingConfigs {
        config {
            keyAlias 'ceshikey'
            keyPassword '091838'
            storeFile file('D:/text.jks')
            storePassword '091838'
        }

    }
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.achers.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        flavorDimensions "versionCode"

    }
    buildTypes {

        debug {
            minifyEnabled false
            debuggable true
        }

        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
            debuggable false
        }

    }


    productFlavors {
        //配置多渠道
        uc {   //uc
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]
        }
        _360 {  //360
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]
        }
        baidu {  //百度
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
        }
        yyb {  //應用寶
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yyb"]
        }

        //配置包的環境 和 替換包名  
//        url{
                //主機地址 
//            applicationId "com.host.myapplication"
//        }
//        urlonline{
                //線上地址
//            applicationId "com.online.myapplication"
//        }
//        urltest{
                //測試地址
//            applicationId "com.test.myapplication"
//        }

    }

}





dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    api 'com.jakewharton:butterknife:8.4.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
    implementation 'com.google.code.gson:gson:2.2.4'
    implementation 'com.zhy:okhttputils:2.6.2'
    implementation 'org.greenrobot:eventbus:3.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'com.android.support:design:26.1.0'
}

我們這裏還有更加簡潔的寫法 效果是一樣的


    productFlavors {
        //配置多渠道
        uc {}
        _360 {}
        baidu {}
        yyb {}

        //配置包的環境 和 替換包名
//        url{
                //主機地址
//            applicationId "com.host.myapplication"
//        }
//        urlonline{
                //線上地址
//            applicationId "com.online.myapplication"
//        }
//        urltest{
                //測試地址
//            applicationId "com.test.myapplication"
//        }

    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }

另外
我們寫完之後可以用Gradle Project 來指定生成apk
Gradle Project

好的 我們這樣打包其實是很慢的

所以推薦用美團的打包策略
https://tech.meituan.com/mt-apk-packaging.html

這裏就不說了 太多資料了 結合Python 更好,更快。

拓展
Build Variants(構建變種版本)
開發每次調試接口,我們可能會需要配置3個URL

public final static String URL = "主機環境:---10.18.3.1";
public final static String URL = "線上環境:---10.18.3.1";
public final static String URL = "測試環境:---10.18.3.1";

其實就是給測試的兄弟 打三個不同地址的包
我們如果一個一個去改 去打 畢竟麻煩

所以我們來操作下
不需要,改代碼,要選擇運行那個環境直接切換,方便快捷

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這樣我們能在同一個手機上同時裝上不同環境的包了

實用的module分層

新建config.gradle

可以在根目錄下建個config.gradle,然後只需在根目錄下build.gradle最頂部加上下面一行代碼,然後同步下,意思就是所有的子項目或者所有的modules都可以從這個配置文件裏讀取內容。

apply from: "config.gradle"

config.gradle

ext {

android = [
        compileSdkVersion: 26,  
        buildToolsVersion: "26.0.0",       
        minSdkVersion    : 15,
        targetSdkVersion : 26,

]

dependencies = [
        appcompatV7': 'com.android.support:appcompat-v7:26.1.0',
        design      : 'com.android.support:design:26.1.0'

]

}

app/build.gradle

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        applicationId "com.example.achers.myapplication"
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }

...

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile rootProject.ext.dependencies.appcompatV7
    compile rootProject.ext.dependencies.design
}

開發代碼混淆規則

混淆能讓反編譯的代碼可讀性變的很差,而且還能顯著的減少APK包的大小。

第一個技巧

相信很多朋友對混淆都覺得麻煩,甚至說,非常亂。因爲添加混淆規則需要查詢官方說明文檔,甚至有的官方文檔還沒說明。當你引用了太多庫後,添加混淆規則將使一場噩夢。
這裏介紹一個技巧,不用查官方文檔,不用逐個庫考慮添加規則。
首先,除了默認的混淆配置(android-sdk/tools/proguard/proguard-android.txt), 自己的代碼肯定是要自己配置的:

## 位於module下的proguard-rules.pro
#####################################
######### 主程序不能混淆的代碼 #########
#####################################

-dontwarn xxx.model.**
-keep class xxx.model.** { *; }

## 等等,自己的代碼自己清楚

#####################################
########### 不優化泛型和反射 ##########
#####################################

-keepattributes Signature

接下來是麻煩的第三方庫,一般來說,如果是極光推的話,它的包名是cn.jpush, 添加如下代碼即可:

-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }

其他的第三庫也是如此,一個一個添加,太累!其實可以用第三方反編譯工具(比如jadx:https://github.com/skylot/jadx ),打開apk後,一眼就能看到引用的所有第三方庫的包名,把所有不想混淆或者不確定能不能混淆的,直接都添加又有何不可:

#####################################
######### 第三方庫或者jar包 ###########
#####################################

-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }

-dontwarn com.squareup.**
-keep class com.squareup.** { *; }

-dontwarn com.octo.**
-keep class com.octo.** { *; }

-dontwarn de.**
-keep class de.** { *; }

-dontwarn javax.**
-keep class javax.** { *; }

-dontwarn org.**
-keep class org.** { *; }

-dontwarn u.aly.**
-keep class u.aly.** { *; }

-dontwarn uk.**
-keep class uk.** { *; }

-dontwarn com.baidu.**
-keep class com.baidu.** { *; }

-dontwarn com.facebook.**
-keep class com.facebook.** { *; }

-dontwarn com.google.**
-keep class com.google.** { *; }

## ... ...

第二個技巧
一般release版本混淆之後,像友盟這樣的統計系統如果有崩潰異常,會記錄如下:

java.lang.NullPointerException: java.lang.NullPointerException
    at com.xxx.TabMessageFragment$7.run(Unknown Source)

這個Unknown Source是很要命的,排除錯誤無法定位到具體行了,大大降低調試效率。
當然,友盟支持上傳Mapping文件,可幫助定位,mapping文件的位置在:

project > module
        > build > outputs > {flavor name} > {build type} > mapping.txt

如果版本一多,mapping.txt每次都要重新生成,還要上傳,終歸還是麻煩。
其實,在proguard-rules.pro中添加如下代碼即可:

-keepattributes SourceFile,LineNumberTable 

當然apk包會大那麼一點點(我這裏6M的包,大個200k吧),但是再也不用mapping.txt也能定位到行了,爲了這種解脫,這個代價我個人覺得是值的,而且超值!

參考文章
http://blog.csdn.net/zivensonice/article/details/51672846
https://www.cnblogs.com/qianxudetianxia/p/4948499.html

https://mp.weixin.qq.com/s?__biz=MzI4MTQyNDg3Mg==&mid=2247484168&idx=1&sn=b60e96bdaa87038bfc1f449c492efe9f&chksm=eba8258fdcdfac9963a5f0f0d6dc6273f1d7ede8a2cbe294891573bde127352fce3b34e80e29&mpshare=1&scene=23&srcid=1113Lp8G5zqyfNdxx94RVfa3#rd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章