告訴你我知道的多渠道打包

多渠道打包有什么用我就不說了,其實還不是上面提出的需求,為了這些需求,那我們也只能依法實現(xiàn)了。下面給大家介紹一下我平時寫的多渠道打包,
不過于深入研究其原理,因為在具體的我也說不出來,只是介紹實現(xiàn)的需求。

需求

產(chǎn)品:給我打四個包,我要這四個包應(yīng)用同時裝到一個手機(jī)上,每個應(yīng)用名不一樣,應(yīng)用圖標(biāo)不一樣,打開軟件后顯示的也不一樣。
碼農(nóng):。。。呵呵

新建項目

新建項目之后,修改工程最外層build.gradle文件,目的在于統(tǒng)一管理。

    //所有的版本編譯工具在此定義
    ext {
        //SDK和編譯工具的版本
        compileSdkVersion = 25
        buildToolsVersion = '25.0.0'
        minSdkVersion = 15
        targetSdkVersion = 25
        //項目依賴庫的版本
        supportLibraryVersion = "25.0.0"
    }

如圖:



添加之后,自然要用它了,不然改了干啥,在module層級的build.gradle文件里android大括號里面修改一下原有配置。

    android{
        compileSdkVersion rootProject.ext.compileSdkVersion
        buildToolsVersion rootProject.ext.buildToolsVersion
        
        
        
            defaultConfig {
                applicationId "com.example.huangcl.manychannel"
                minSdkVersion rootProject.ext.minSdkVersion
                targetSdkVersion rootProject.ext.targetSdkVersion
                versionCode Integer.valueOf(VERSIONCODE)//VERSIONCODE,你會好奇這是哪里來的
                versionName VERSIONNAME//VERSIONNAME這個也是
                testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            }
            ...
        }
        
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"http://在這里用supportLibraryVersion
        testCompile 'junit:junit:4.12'
    }

代碼里面的兩個值,是通過在app層級下新建的一個文件名字叫g(shù)radle.properties,這里你也可以叫其他,但一定要.properties后綴,因為Java本身對.properties文件支持。
然后在文件里面寫:

    //版本信息
    VERSIONCODE=1
    VERSIONNAME=1.0.0

得是.properties結(jié)尾。

多渠道步驟一:不同的應(yīng)用名和圖標(biāo)

在清單配置文件里application層級中meta-data接入

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.huangcl.manychannel">
    
        <application
            android:allowBackup="true"
            android:icon="${app_icon}"http://圖標(biāo)不同不能寫死了
            android:label="${app_name}"http://同
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            //接入友盟
            <meta-data
                android:name="UMENG_CHANNEL"
                android:value="${CHANNEL_ID}" />
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>

接著在app層級下的build.gradle申明接入友盟的渠道。

      //通用渠道映射項 def 表示申明
     def flavorHash = [UMENG_APPKEY: UMENG_APPKEY];//UMENG_APPKEY友盟的Appkey,同樣寫在你新建的gradle.properties文件中
     //渠道分析
     //productFlavors,不同定制的產(chǎn)品
        productFlavors {
    
            //開發(fā)階段
            manychannel_debug {       
              //冒號前邊的是清單文件里設(shè)置的鍵,后邊的是值,CHANNEL_DEBUG同樣寫在你新建的gradle.properties文件中,下面渠道的也一樣
                manifestPlaceholders = [CHANNEL_ID: CHANNEL_DEBUG,
                                        app_icon  : "@mipmap/ic_launcher",
                                        app_name  : "測試版本"]
            }
            //內(nèi)部測試階段
            manychannel_firim {
                manifestPlaceholders = [CHANNEL_ID: CHANNEL_FIRIM,
                                        app_icon  : "@mipmap/ic_money",
                                        app_name  : "fir版本"]
            }
            //豌豆夾
            manychannel_wandoujia {
                manifestPlaceholders = [CHANNEL_ID: CHANNEL_WANDOUJIA,
                                        app_icon  : "@mipmap/ic_pay",
                                        app_name  : "豌豆莢版本"]
            }
            //360市場
            manychannel_sanliuling {
                manifestPlaceholders = [CHANNEL_ID: CHANNEL_SANLIULING,
                                        app_icon  : "@mipmap/ic_wechat",
                                        app_name  : "360版本"]
            }
    
        }

productFlavors背后的延伸
這樣簡單的多渠道就出來了,如圖:

多渠道步驟二:不同的應(yīng)用的包名

做完步驟二你會發(fā)現(xiàn)并不能把四個包裝到同一個手機(jī)上,那是你沒有對渠道進(jìn)行分析,配置,下面來分析渠道。

    //映射渠道分析
    // productFlavors.all{}表示遍歷上面定義的渠道,flavor ->flavor.manifestPlaceholders.putAll(flavorHash)(manifestPlaceholders 是上面定義的名字)這表示
    //把flavorHash集合里面的值加到flavor里面在返還回去(Groovy語法),就等于抽出上面productFlavors的共性,其實app_icon,app_name也可以抽到flavorHash中.
    
    productFlavors.all {
            //遍歷
        flavor ->
            flavor.manifestPlaceholders.putAll(flavorHash);
            //println flavor
            if (flavor.name.equals("manychannel_debug")) {
                flavor.versionCode = Integer.valueOf(VERSIONCODE_DEV);//設(shè)置版本號
                flavor.versionName = VERSIONNAME_DEV;//設(shè)置版本名,同樣寫在你新建的gradle.properties文件中
                flavor.applicationId = "com.example.huangcl.manychannel_debug"http://設(shè)置包名

            } else if (flavor.name.equals("manychannel_firim")) {
                flavor.versionCode = Integer.valueOf(VERSIONCODE);
                flavor.versionName = VERSIONNAME;
                flavor.applicationId = "com.example.huangcl.manychannel_fir"

            } else if (flavor.name.equals("manychannel_wandoujia")) {
                flavor.versionCode = Integer.valueOf(VERSIONCODE);
                flavor.versionName = VERSIONNAME;
                flavor.applicationId = "com.example.huangcl.manychannel_wandoujia"

            } else if (flavor.name.equals("manychannel_sanliuling")) {
                flavor.versionCode = Integer.valueOf(VERSIONCODE);
                flavor.versionName = VERSIONNAME;
                flavor.applicationId = "com.example.huangcl.manychannel_sanliuling"
            }
    }

多渠道步驟三:不同的應(yīng)用顯示不同的內(nèi)容

這塊就得在代碼里面實現(xiàn)了,思路很簡單,就是取道清單配置文件中的meta-data的值,注意是application層級的,取到之后判斷不同的值,不同的操作就行了。代碼:

    public class MainActivity extends AppCompatActivity {
    
        TextView infoTxt;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            infoTxt = (TextView) findViewById(R.id.infoTxt);
    
    
            ApplicationInfo appInfo = null;
            try {
                appInfo = this.getPackageManager()
                        .getApplicationInfo(getPackageName(),
                                PackageManager.GET_META_DATA);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            String msg=appInfo.metaData.getString("UMENG_CHANNEL");
            Log.i("chun", msg);
            //println flavor
            if ("debug".equals(msg)) {
                infoTxt.setText("manychannel_debug");
            } else if ("fir.im".equals(msg)) {
                infoTxt.setText("manychannel_firim");
            } else if ("zhushou.#".equals(msg)) {
                infoTxt.setText("manychannel_sanliuling");
            }else if ("wandoujia.com".equals(msg)) {
                infoTxt.setText("manychannel_wandoujia");
            }
        }
    }

其它

打包的時候,需要簽名配置信息,密碼等等的,你可以把.jks文件放到app層級下面。如圖:



不多說了,下面貼我完整的build.gradle文件和新建的gradle.properties文件內(nèi)容。

  • build.gradle

          apply plugin: 'com.android.application'
          
          android {
              compileSdkVersion rootProject.ext.compileSdkVersion
              buildToolsVersion rootProject.ext.buildToolsVersion
          
          
          
              defaultConfig {
                  applicationId "com.example.huangcl.manychannel"
                  minSdkVersion rootProject.ext.minSdkVersion
                  targetSdkVersion rootProject.ext.targetSdkVersion
                  versionCode Integer.valueOf(VERSIONCODE)//gradle.properties文件中
                  versionName VERSIONNAME
                  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
              }
          
              //聲明簽名信息
              signingConfigs {
                  release {
                      keyAlias KEYALIAS//gradle.properties文件中
                      keyPassword KEYPASSWORD//gradle.properties文件中
                      storeFile file(STOREFILE)//gradle.properties文件中
                      storePassword STOREPASSWORD//gradle.properties文件中
                  }
              }
          
          
              buildTypes {
                  //發(fā)行版
                  release {
                      minifyEnabled true
                      //gradle.properties文件中
                      proguardFiles getDefaultProguardFile(PROGUARD_ANDROID), PROGUARD_RULES
                      //簽名信息
                      signingConfig signingConfigs.release
                  }
                  //debug版
                  debug {
                      minifyEnabled false
                      proguardFiles getDefaultProguardFile(PROGUARD_ANDROID), PROGUARD_RULES
                      //簽名信息
                      signingConfig signingConfigs.release
                  }
          
              }
          
              //渠道分析
              productFlavors {
          
                  //開發(fā)階段
                  manychannel_debug {
                      manifestPlaceholders = [CHANNEL_ID: CHANNEL_DEBUG,
                                              app_icon  : "@mipmap/ic_launcher",
                                              app_name  : "測試版本"]
                  }
                  //內(nèi)部測試階段
                  manychannel_firim {
                      manifestPlaceholders = [CHANNEL_ID: CHANNEL_FIRIM,
                                              app_icon  : "@mipmap/ic_money",
                                              app_name  : "fir版本"]
                  }
                  //豌豆夾
                  manychannel_wandoujia {
                      manifestPlaceholders = [CHANNEL_ID: CHANNEL_WANDOUJIA,
                                              app_icon  : "@mipmap/ic_pay",
                                              app_name  : "豌豆莢版本"]
                  }
                  //360市場
                  manychannel_sanliuling {
                      manifestPlaceholders = [CHANNEL_ID: CHANNEL_SANLIULING,
                                              app_icon  : "@mipmap/ic_wechat",
                                              app_name  : "360版本"]
                  }
          
              }
              //通用渠道映射項
              def flavorHash = [UMENG_APPKEY: UMENG_APPKEY];
          
              //映射渠道分析
              productFlavors.all {
                      //
                  flavor ->
                      flavor.manifestPlaceholders.putAll(flavorHash);
                      //println flavor
                      if (flavor.name.equals("manychannel_debug")) {
                          flavor.versionCode = Integer.valueOf(VERSIONCODE_DEV);
                          flavor.versionName = VERSIONNAME_DEV;
                          flavor.applicationId = "com.example.huangcl.manychannel_debug"
          
                      } else if (flavor.name.equals("manychannel_firim")) {
                          flavor.versionCode = Integer.valueOf(VERSIONCODE);
                          flavor.versionName = VERSIONNAME;
                          flavor.applicationId = "com.example.huangcl.manychannel_fir"
          
                      } else if (flavor.name.equals("manychannel_wandoujia")) {
                          flavor.versionCode = Integer.valueOf(VERSIONCODE);
                          flavor.versionName = VERSIONNAME;
                          flavor.applicationId = "com.example.huangcl.manychannel_wandoujia"
          
                      } else if (flavor.name.equals("manychannel_sanliuling")) {
                          flavor.versionCode = Integer.valueOf(VERSIONCODE);
                          flavor.versionName = VERSIONNAME;
                          flavor.applicationId = "com.example.huangcl.manychannel_sanliuling"
                      }
              }
          
          }
          
          dependencies {
              compile fileTree(dir: 'libs', include: ['*.jar'])
              androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
                  exclude group: 'com.android.support', module: 'support-annotations'
              })
              compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
              testCompile 'junit:junit:4.12'
          }
    
  • gradle.properties

          //混淆信息
          PROGUARD_ANDROID=proguard-android.txt
          PROGUARD_RULES=proguard-rules.pro
          //版本信息
          VERSIONCODE=1
          VERSIONNAME=1.0.0
          VERSIONCODE_DEV=2
          VERSIONNAME_DEV=1.1.0
          
          //友盟(值亂填的)
          UMENG_APPKEY=fdsgdffdfhsjfhdsifbdhjsf
          
          //渠道信息
          CHANNEL_DEBUG=debug
          CHANNEL_DEBUG_NAME="測試版本"
          CHANNEL_FIRIM=fir.im
          CHANNEL_FIRIM_NAME="fir版本"
          CHANNEL_WANDOUJIA=wandoujia.com
          CHANNEL_WANDOUJIA_NAME="豌豆莢版本"
          CHANNEL_SANLIULING=zhushou.#
          CHANNEL_SANLIULING_NAME="360版本"
          
          
          //簽名配置信息(都不是秘密)
          KEYALIAS=hcl
          KEYPASSWORD=hs19931010
          STOREFILE=./hcl.jks
          STOREPASSWORD=hs19931010
    

結(jié)果

  • 同一手機(jī)
  • 不同顯示

    測試版

    fir版

豌豆莢版

![](https://github.com/mar-sir/Manychannels/blob/master/Manychannel/app/src/main/java/images/result_4.jpg?raw=true)

360版

![](https://github.com/mar-sir/Manychannels/blob/master/Manychannel/app/src/main/java/images/result_5.jpg?raw=true)

源碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,176評論 25 708
  • 這一章主要針對項目中可以用到的一些實用功能來介紹Android Gradle,比如如何隱藏我們的證書文件,降低風(fēng)險...
    acc8226閱讀 7,971評論 3 25
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,644評論 19 139
  • 轉(zhuǎn)至:http://blog.csdn.net/heqiangflytosky/article/details/5...
    kkgo閱讀 3,031評論 0 1
  • 知道今天為什么不快樂嗎? 因為沒看書 其實幸福很簡單 一本書就夠了 極簡
    與綠有緣閱讀 393評論 0 2

友情鏈接更多精彩內(nèi)容