Gradle實現編譯差異


今天開發組長問了這么一個問題,如何實現通過gradle編譯動態設置代碼里的一些值。可能這么說不太明白,下面說依稀具體需求。

開發中有兩個服務器:一個用於測試版本、一個用於線上版本發布,這兩個服務器地址不同。現在想通過在編譯版本的時候,不去手動更改服務器地址,而是編譯測試版本時,代碼中使用的地址就是測試服務地址,編譯線上版本時,使用線上服務地址。如何實現? 實現原理和多渠道打包是一樣的。下面展示代碼:

(1) 在App的AndroidManifest.xml文件中Application節點下添加:

<meta-data
            android:name="DATA_NAME"
            android:value="${DATA_NAME_VALUE}" />

(2)在App的build.gradle文件中添加:

defaultConfig {
        applicationId "com.gradle.asdemo"
        versionCode Integer.parseInt(project.VERSION_CODE)
        versionName project.VERSION_NAME
        minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
        targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        manifestPlaceholders = [DATA_NAME_VALUE: "http://www.mamami.com"] //設置默認的值
    }

    productFlavors {
        ol {
            manifestPlaceholders = [DATA_NAME_VALUE: "http://www.mamami.com"] //線上服務地址
        }
        test {
            manifestPlaceholders = [DATA_NAME_VALUE: "http://192.168.58.38"] //測試服務地址
        }
    }

 (3) 在代碼中獲取服務地址的值

public static String getAppMetaData(Context context, String meta_name) {
        try {
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return appInfo.metaData.getString(meta_name);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

public static String getHost(Context context) {
        String hostURL = getAppMetaData(context, "DATA_NAME");
        if (hostURL != null) {
            return hostURL;
        }

        return DEFUALT_HOST;
    }

  這樣在編譯時通過選擇不同的Flavor就可以動態改變服務地址。這里說一下,在我們平時開發debug開發編譯獲取到的地址並不是默認值,而是好像在按照Flavor中設置的name的字典順序拿到的。

(4)可能遇到的問題:Error:(74, 13) Attribute meta-data#xxx@value at AndroidManifest.xml:74:13 requires a placeholder substitution but no value for <YOUMI_CHANNEL_VALUE> is provided

解決方案:(兩處取證說明正確)——其實我遇到這個問題不是這個原因,這是意外收獲。后續我會說明我的那種情況造成這個問題的原因

http://www.tuicool.com/articles/BRNfeiU

http://stackoverflow.com/questions/37368124/gradle-manifest-requires-a-placeholder-substitution-error-but-manifestplacehol

(5)拓展:

  使用manifestPlaceholders的這種配置,同樣適用於manifest的其他配置。比如你需要在不同渠道發布的apk里面,指定不同的啟動Activity。比如在豌豆莢里面發布的,啟動的Activity顯示的是豌豆莢首發的界面,應用寶里面啟動的是應用寶首發的界面,你就可以對你的activity的值使用${activity_name}的方式,然后在productFlavors里面配置這個${activity_name}的值。

 

(6)參考:

http://blog.csdn.net/mynameishuangshuai/article/details/51783303

http://blog.csdn.net/maosidiaoxian/article/details/42000913


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM