多渠道打包的用途
- 用途一:統(tǒng)計不同渠道的數(shù)據(jù),方便在推廣運營過程中進行有效的渠道比較。來評估渠道的質(zhì)量。
- 用途二:對于APP內(nèi)部有分享邀請好友送獎勵的活動,需要進行渠道標識,免除用戶手動輸入邀請碼的流程。
簡化用戶注冊步驟,減少因注冊步驟太繁瑣而導致的用戶流失。 - 用途三:部分游戲要進行分渠道的推廣,需要進行分包統(tǒng)計。
- 分包的方式:
- 客戶端打多個渠道包:以下方式都使用
- 服務(wù)器根據(jù)需要動態(tài)生成渠道包:使用較多的為美團和360的方式
多渠道打包的6種方式
- 1、原始多渠道打包
- 直接在清單文件中定義meta標簽設(shè)置渠道值,讀取對應(yīng)值當做渠道id;
- 或者直接將渠道寫入java代碼中
- 優(yōu)缺點:操作簡單,但是當渠道數(shù)量過多時消耗時間過長,需要多次修改id值。
- 2、通過將渠道信息寫入assets中進行渠道標識
- 3、友盟多渠道打包
- 原理:清單文件添加渠道標簽讀取對應(yīng)值。
- 打包后修改渠道值的兩種方法
- 第一種方法:
通過ApkTool進行解包,然后修改AndroidManifest中修改渠道標示,最后再通過ApkTool進行打包、簽名。 - 第二種方法:
使用AXML解析器axmleditor.jar,擁有很弱的編輯功能,工程中用來編輯二進制格式的 AndroidManifest.xml 文件.
- 4、美團多渠道打包
- 1、直接將apk文件解壓縮,然后在META-INF中間中添加以渠道名命名的空文件。
- 2、代碼中讀取該文件名作為渠道名。
- 該種方式不需要重新對apk進行簽名,操作簡單,也可將添加渠道文件的步驟做成Python腳本。實現(xiàn)自動化添加
- 優(yōu)缺點:需要將apk解壓縮,如果APK包較大則解壓縮所需時間較長。
- 使用遇到的問題:使用愛加密加密過后,再按此種方式進行渠道包的添加,會導致在7.0及以上手機上無法安裝
- 解決辦法:先分渠道打多個包,然后提交愛加密進行加密。
- 5、360多渠道打包
- 利用的是Zip文件“可以添加comment(摘要)”的數(shù)據(jù)結(jié)構(gòu)特點,在文件的末尾寫入任意數(shù)據(jù),而不用重新解壓zip文件
- apk文件就是zip文件格式;
- 注釋的讀取即渠道標識的讀取
- 不需要對apk文件解壓縮和重新簽名即可完成多渠道自動打包,高效速度快,無兼容性問題
- 6、Gradle和Maven多渠道打包
參考:https://blog.csdn.net/yancey_blog/article/details/52743864
Maven是一個軟件項目管理和自動構(gòu)建工具;
配合使用android-maven-plugin插件,以及maven-resources-plugin插件可以很方便的生成渠道包
Maven打包尚未使用過
-
Gradle多渠道打包
第一步:在清單文件中定義渠道 <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}" /> 第二步:在build.gradle中動態(tài)替換渠道值 productFlavors { wandoujia { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"] } baidu { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"] } c360 { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "c360"] } uc { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"] } } 第二步可替換為如下方式: productFlavors { wandoujia {...}//支持在{}定義屬性 baidu {...} c360 {...} uc {...} productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] } } <!--1、添加channels.properties渠道信息配置文件--> #默認渠道 channel.default=paojiao #全部渠道列表 channel.list=baidu,c360,uc12345 apply from: "../channels.gradle"1 productFlavors { for (int i = 0 ; i < channelArray.size(); i++) { def channel = channelArray[i] "${channel}"{ manifestPlaceholders = [CHANNEL_VALUE: channel] } } } 渠道讀取 private String getChannel(Context context) { try { PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); return appInfo.metaData.getString("channel"); } catch (PackageManager.NameNotFoundException ignored) { } return ""; }