Gradle實戰:不一樣編譯類型的包同設備共存

1、需求背景

在測試階段,有時須要在同一個設備上同時安裝debug、beta、release等不一樣編譯類型的包,或者同時安裝當前版本與某個歷史版本的包,以方便比較查看;可是,在同一個設備上,一個包名只能安裝一個應用,本文將圍繞該問題介紹完整的解決方案。android


2、實踐

1. 基本概念

在上一篇文章《 Gradle實際應用(一):批量打包》中咱們已經介紹過packageapplicationIdPlaceHolder的概念,本文主要經過這三個參數來實現多包共存。sql

2. 修改應用名稱

  • AndroidManifest文件中的label採用PlaceHolder的形式,使其能夠在build.gradle文件中動態賦值,所以實現不一樣的編譯類型有不一樣的應用名稱數據庫

    <application
        android:name="com.company.appname.myApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="${app_label}"         //將label值設置爲變量
        android:theme="@style/Theme.AppCompat.NoActionBar"
        tools:replace="android:icon,android:theme,android:label">
  • 增長string值api

    <string name="app_name">Test</string>
    <string name="app_name_beta">Test-beta</string>
    <string name="app_name_debug">Test-debug</string>
  • 同理,咱們也可實現對icon的修改。android-studio

3. build.gradle文件中配置:

  • debug爲例app

    //設置全局變量,做爲開關
    def isCoexist = false; //須要多包共存時設爲true
    
    /**
     * 若是採用jekins打包時,執行命令:./gradlew assembleDebug -DmultiApp='true'
     * 若是採用AS打包時,修改變量:isCoexist = true
     */
    String appId = defaultConfig.applicationId // 讀取原始的applicationId
    String multiApp = System.properties['multiApp'] // 讀取打包命令中設置的系統參數
    if (isCoexist) {
        multiApp = "true"
    }
    debug() {
        if ("${multiApp}" != "${null}") { //採用該方式是由於某些機器上equals方法失效,暫無解
            appId = defaultConfig.applicationId + ".debug"  //拼上後綴
            applicationIdSuffix ".debug" //拼上後綴(gradle自帶方法)
        }
        manifestPlaceholders = [app_label: "@string/app_name_debug"]  // AndroidManifest文件中的label就會被賦值
        println "applicationId: " + appId + " (debug)"
    }

4. Failure [INSTALL_FAILED_CONFLICTING_PROVIDER] 問題解決

若是應用中未使用ContentProvider,則上述配置便可;若是使用了ContentProvider,好比集成了個推推送,其中有一個DownloadProvider,所以安裝時會報錯,解決參考,解決以下:maven

// 在AndroidManifest文件中,修改authorities,如:
<provider
    android:name="com.igexin.download.DownloadProvider"
    android:authorities="downloads.com.company.appname.contentprovider"
    android:process=":pushservice"/>

改成:

<provider
    android:name="com.igexin.download.DownloadProvider"
    android:authorities="downloads.${DownloadProvider}.contentprovider"
    android:process=":pushservice"/>

相應地,在build.gradle文件中添加DownloadProvider的賦值:

manifestPlaceholders = [app_label: "@string/app_name_debug", DownloadProvider: appId]

5. 第三方應用appkey驗證失敗問題解決

以百度地圖爲例,百度地圖須要開發者在其開放平臺以包名和簽名爲應用註冊一個appkey,生成的appkey填寫在AndroidManifest文件中,以下:ide

<meta-data
   android:name="com.baidu.lbsapi.API_KEY"
   android:value="your_baidu_appkey"/>

此時,咱們若是安裝debug包,則包名變成了com.company.appname.debug,那麼,appkey就沒法驗證經過了,百度地圖也將沒法展現。試想,咱們可否修改百度地圖驗證時上傳的包名呢?然而,通過一番努力,查看了百度地圖sdk包,咱們沒法實現這一點。那麼,只能爲測試包申請一個appkey了,而後再經過PlaceHolder動態地設值。相應的修改以下:

<meta-data
   android:name="com.baidu.lbsapi.API_KEY"
   android:value="${BaiduMap_API_KEY}"/>

build.gradle文件中,以debug爲例,修改以下:

manifestPlaceholders = [app_label: "@string/app_name_debug", DownloadProvider: appId, 
                        BaiduMap_API_KEY: your_baidu_appkey_debug]

深刻學習

相關文章
相關標籤/搜索