1. 程式人生 > >Android Studio Gradle 多渠道自動打包,動態修改HostUrl,簽名apk,混淆配置詳解

Android Studio Gradle 多渠道自動打包,動態修改HostUrl,簽名apk,混淆配置詳解

  文/ skay

最近遇到專案從Eclispe遷移到Android studio,以前的Ant自動打包指令碼已經相容不好了,所以用了Gradle實現打渠道包,切換環境等,

Ant打包指令碼

 <target name="-release-sign" if="has.keystore">
        <!-- only create apk if *not* a library project -->
        <do-only-if-not-library elseText="Library project: do not create apk...">
            <sequential>
                <property name="out.unaligned.file"
                          location="${out.absolute.dir}/${ant.project.name}-release-unaligned.apk"/>

                <!-- Signs the APK -->
                <echo level="info">Signing final apk with your  apk signer server...</echo>
                <taskdef resource="com/myapk/ant/task/defaults.properties" classpath="${signer.jar}"/>
                <apk-signer
                        server="http://xxx.com/packservice/sign<pre name="code" class="html" style="font-size: 14px; line-height: 26px;">
</pre><p><pre name="code" class="html">" apk="${out.packaged.file}" dest="${out.unaligned.file}" prodkey="${singer.prodkey}" verbose="true" timeout="500" retries="5" /> <!-- Zip aligns the APK --> <zipalign-helper in.package="${out.unaligned.file}" out.package="${out.final.file}"/> <echo level="info">Release Package: ${out.final.file}</echo> </sequential> </do-only-if-not-library> <record-build-info/> </target>


 Gradle

    加入配置,簽名檔案,配置打包生成apk檔名稱規則,配置url,配置渠道等

配置gradle

android {}配置一些關於android的基本配置

1配置依賴關係

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:support-v4:23.2.1'
    compile 'com.android.support:recyclerview-v7:23.2.1'
   ......
}

如果想相容v4

compile ('com.android.support:recyclerview-v7:22.2.0'){ exclude module: 'support-v4' }



  3配置打包方式

signingConfigs {

        release {
            keyAlias props['KEY_ALIAS']
            keyPassword props['KEY_PASSWORD']
            storeFile file(props['KEYSTORE_FILE'])
            storePassword props['KEYSTORE_PASSWORD']
        }

        debug {
            storeFile file('../../debug.keystore')
            storePassword 'you pass'
            keyAlias 'you key'
            keyPassword 'you pass'
        }

    }
   

     載入簽名配置檔案

Properties props = new Properties()
    props.load(new FileInputStream(file("signing.properties")))

   簽名檔案 signing.properties 配置如下:
KEY_ALIAS = xxxx
KEY_PASSWORD = 你的密碼
KEYSTORE_FILE = ../../nide.keystroe (相對路徑)
KEYSTORE_PASSWORD =密碼

   簽名你自己可生成,可以直接用eclispe生成的。


三 配置環境

 定義線上環境Url

def host_url = "https://xxx.com";

四 配置混淆

 開啟混淆開關:

minifyEnabled true

開啟過濾非引用資源打包 :

shrinkResources true

開啟log輸出:

buildConfigField "boolean", "LOG_DEBUG", "true"

定義打包方式:

buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            buildConfigField "boolean", "LOG_DEBUG", "false"
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }


        debug {
            minifyEnabled true
            shrinkResources true
            buildConfigField "boolean", "LOG_DEBUG", "true"
            signingConfig signingConfigs.debug
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

編譯專案後 會生成buildConfig檔案

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  // app id
  public static final String APPLICATION_ID = "com.skay.test";
  public static final String BUILD_TYPE = "debug";
  // 渠道
  public static final String FLAVOR = "dev";
  // 版本
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from the variant
  public static final String APP_ENV = "dev ";
  // host
  public static final String HOST_URL = " http://aaa.com/";
  // Fields from build type: debug
  public static final boolean LOG_DEBUG = true;
}

 程式碼中可以用上面的變數做一些判斷。

五 配置打包指令碼

 // 指定輸出的apk名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            // 打包型別
            def buildTypeName = variant.buildType.name
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                // 包名稱
                def flavorName = variant.productFlavors[0].name
                // 版本名稱
                def versionName = defaultConfig.versionName
                // 開發環境
                buildConfigField "String", "APP_ENV", "\"${flavorName} \""
                // 修改打包環境的url
                buildConfigField "String", "HOST_URL", "\" ${host_url}\""
                // yourapkname_release_myapk_ver1.0.0_build20130312.apk 輸出格式
                def fileName = "${PRODUCT_NAME}_${buildTypeName}_${flavorName}_env${flavorName}_ver${versionName}_build${BUILD_TIME_FORMAT}.apk"

                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }

六 切換渠道

//修改渠道號
    productFlavors {

        // 線上版本 
         release{
         }

        //開發版本,
        dev {
            host_url = "http://xxxx1.com./"

        }

        //Qa測試版本
        qa{
             host_url = "http://xxx2.com/"
         }

    }


    這樣我們在打包時 只要你開啟你要的那個版本,buildConfig將會修改,輸出包就可以了, 不僅切換了Url,而且還制定了渠道版本,非常方便

 六 新增對jar的支援

    有時候從eclispe移植過來時,返現jar無法載入,找不到地址

 在android {}加入以下配置

sourceSets {
        main {
            jniLibs.srcDir 'libs'
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }

七 新增對ndk的支援

如果so找不到 請配置對四個不同cpu的支援

在android {}加入以下配置

 defaultConfig {
       .......
    
      ndk {
       abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
      }
    }


混淆相關:

配置proguard-rules.pro檔案

# 混淆時不使用大小寫混合,混淆後的類名為小寫
# windows下的同學還是加入這個選項吧(windows大小寫不敏感)
-dontusemixedcaseclassnames

# 如果應用程式引入的有jar包,並且想混淆jar包裡面的class
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共的庫的類的成員
-dontskipnonpubliclibraryclassmembers

# 有了verbose這句話,混淆後就會生成對映檔案
# 包含有類名->混淆後類名的對映關係
# 然後使用printmapping指定對映檔案的名稱
-verbose
-ignorewarnings

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
# 不做預檢驗,preverify是proguard的四個步驟之一
# Android不需要preverify,去掉這一步可以加快混淆速度
-dontpreverify

# If you want to enable optimization, you should include the following:
# 混淆採用的演算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
# 設定混淆的壓縮比率 0 ~ 7
-optimizationpasses 5
-allowaccessmodification

# 保護程式碼中的Annotation不被混淆
# 這在JSON實體對映時非常重要,比如fastJson
-keepattributes *Annotation*

# 避免混淆泛型
# 這在JSON實體對映時非常重要,比如fastJson
-keepattributes Signature

# 丟擲異常時保留程式碼行號
-keepattributes SourceFile,LineNumberTable

# Add any project specific keep options here:
# 保留了繼承自Activity、Application這些類的子類
# 因為這些子類有可能被外部呼叫
# 比如第一行就保證了所有Activity的子類不要被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View
-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService


# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
# 所有native的方法不能去混淆.
-keepclasseswithmembernames class * {
    native <methods>;
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
#  列舉類不能去混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 某些構造方法不能去混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# aidl檔案不能去混淆.
# 保留Parcelable序列化的類不能被混淆
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}


# 保留Serializable 序列化的類不被混淆
-keep class * implements java.io.Serializable {
    public *;
}

-keepclassmembers class * implements java.io.Serializable {
   static final long serialVersionUID;
   private static final java.io.ObjectStreamField[] serialPersistentFields;
   !static !transient <fields>;
   private void writeObject(java.io.ObjectOutputStream);
   private void readObject(java.io.ObjectInputStream);
   java.lang.Object writeReplace();
   java.lang.Object readResolve();
}

# 保留Activity中的方法引數是view的方法,
# 從而我們在layout裡面編寫onClick就不會影響
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# 保留自定義控制元件(繼承自View)不能被混淆
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
    public void get*(...);
}

# 對R檔案下的所有類及其方法,都不能被混淆
-keepclassmembers class **.R$* {
    *;
}

# 對於帶有回撥函式onXXEvent的,不能混淆
-keepclassmembers class * {
    void *(**On*Event);
}


 常規混淆配置好,可以增加你專案中的混淆了,如資料模型bean,第三方sdk等
-keep class com.baidu.pushsdk.** { *;}
<pre name="code" class="java">-keep class com.mybisniss.mybean.** { *;}


總結:

好了 以上是常用的gradle打包過程中遇到的坑,都能滿足你對as的需求了,以後遇到再補充

  文/ skay


相關推薦

Android Studio Gradle 多渠道自動打包動態修改HostUrl簽名apk混淆配置

  文/ skay 最近遇到專案從Eclispe遷移到Android studio,以前的Ant自動打包指令碼已經相容不好了,所以用了Gradle實現打渠道包,切換環境等, Ant打包指令碼 <target name="-release-sign"

Android Studio--Gradle多渠道打包

由於國內Android市場眾多渠道,為了統計每個渠道的下載及其它資料統計,就需要我們針對每個渠道單獨打包,如果讓你打幾十個市場的包豈不煩死了,不過有了Gradle,這再也不是事了。友盟多渠道打包廢話不多說,以友盟統計為例,在AndroidManifest.xml裡面會有這麼一

webpack4 css打包、壓縮、分離、去重等優化配置

Webpack 4 目前版本已經到了4.27 相較於前面的版本還是有一些改動的,具體可以參考升級指南 遷移到新版本 這裡只介紹 css 的 打包、壓縮、分離、去重 的方法; 不懂的或者有更優的方案,歡迎評論交流 用到的外掛及loader 外掛描述備註 mini-css-extract-plugin

Android Studio使用Gradle實現自動打包簽名自定義apk檔名多渠道打包整合系統簽名證書【附效果圖附原始碼】

        接觸Android Stuidio有一陣子了,之前用的時候有很多小問題,不過現在的版本感覺已經很好用了,所以準備徹底從Eclipse轉戰Android Stuidio,這段時間把以前經常使用的公用庫都從Eclipse移植過來了,今天研究了一下在Andro

Android利用Gradle多渠道打包如何動態替換資源文字

動態替換APP logo 首先我們在app的build.gradle下面加入如下程式碼,以oem1為示例, productFlavors { oem1 { manifestPlaceholders = [

android studio gradle打包怎麼樣通過打不同的包名所依賴的專案不同即所生成的apk大小不一樣呢(每個apk不包含所有的依賴的專案)

問題:gradle打包,怎麼樣通過打不同的包名所依賴的專案不同,即所生成的apk大小不一樣呢(每個apk不包含所有的依賴的專案)??? 解決:通過修改build.gradle檔案中 在android{}新增如下程式碼:   在dependencies{}中新增 “F

Android Studio Gradle打包實踐之多渠道+版本號管理

上次介紹了 Android Studio的安裝、配置和基本使用 。這次講一下Android Studio用到的打包工具Gradle。 Gradle 是一種構建專案的框架,相容Maven、Ant,為Java專案提供了很多外掛去實現打包功能。廢話不多說,下面直接

Gradle實現自動打包簽名自定義apk文件名

回車 應用 types 背包 sdn 部署 密鑰對 另一個 密鑰庫 Gradle實現自動打包,簽名,自定義apk文件名 什麽是簽名,簽名有什麽用 Android APP都需要我們用一個證書對應用進行數字簽名,不然的話是無法安裝到Android手機上的,平時我們調試運行時到手

Android Studio 打包動態修改aar、apk 包名稱

動態修改AAR名字 android.libraryVariants.all { variant -> if(variant.name.equalsIgnoreCase("rele

cordova整合sencha touch建立APP專案以及Android Studio專案匯入和打包

-------------------目錄結構-------------------------------------------         \app                                                          

android studio Gradle如果不能找依賴的包(Gradle can't find dependency (Android support library))教你如何解決

升級android studio1.0.0正式版以後,突然發現Gradle不能夠新增其他的依賴包,折騰來許久終於找到了解決的辦法,特發帖紀念,留給後面的同學學習。 如果你的android studi

Android Studio Gradle打包使用正式簽名生成apk

在app目錄下找到build.gradle檔案,按照如下配置即可: android { signingConfigs { release { key

Android Studio gradle打包

build生成apk方式 1.android sutidio 選單欄,build-》generate signed apk 隨後可以選擇編譯方式和產品風味 2.在android根目錄下命令列 ./gradlew assemble{BuildType} 對應編譯方式所有productfla

android studio gradle 多版本多apk打包打包系列教程之五)

當然從截圖也可以看出,配置多apk打包和上一篇文章配置多渠道打包是一樣的,都是在productFlavors中配置的。如上圖,我們在productFlavors中配置了兩種flavor的apk資訊一種是Beta版,一種是Releases版,同時每個flavor中我們都重新配置applicationId這個屬性

使用 buck 打包 Android( 使用OkBuck給Android Studio+gradle生成 buck 指令碼)

一、安裝Buck Buck是一個由Facebook推出的開源Android build工具。Buck可以加速你的Android構建,它通過獨立構件並行來發揮多核的效能。進一步的,它還可以通過跟蹤不變

Android Studio Gradle Build Running 太久各版本Gradle的下載Android Studio 2.3 Build 太久

開啟一個新專案或者網上的Demo的時候Buliding時間過長的解決方法原因:本地缺乏對應的gradle,導致Building的時間太長,甚至一直Buiding  當我們在網上下載的Demo什麼的   新開啟的專案太久    關閉專案按方法二即可 在更新Android S

Android 使用Android Studio + Gradle 或 命令列 進行apk簽名打包

官方文件:https://developer.android.com/tools/publishing/app-signing.html 1. 預設為debug mode,使用的簽名檔案在: $

Android Studio無法啟動 開啟 Android Studio gradle下載不了

1.安裝前準備 1.1 安裝 jdk 在安裝AndroidStudio之前請確保你已經安裝了jdk並配置好了,不會安裝的請自行百度。 1.2 下載AndroidStudio 2.安裝 2.1安裝步驟 安裝時一路nxet即可,需要注意的是,你安裝了jd

突然Android studio不能自動引入類了所有的都不行了!!!

正在瘋狂寫程式碼,突然一個奇怪的事情發生了,輸入類名後不能自動引入了,不管是全稱還是前幾個字母。網上查資料就是一個配置勾選auto import。沒問題啊,一直都是勾選的,重啟軟體,不行,新建測試專案,也不行。 最終找到了一個方法,點選下圖選單。果然,好了,不知是為什麼,希

Android Studio獲取開發版SHA1值和發布版SHA1值詳細過程

pre 希望 系統 water target 詳細 andro targe pac 轉自原文 Android Studio獲取開發版SHA1值和發布版SHA1值的史上最詳細方法 前言: 今天我想把百度地圖的定位集成到項目中來,想寫個小小的案例,實現一下,但在集成