Android多渠道打包方案的實踐與優化
目前使用過的多渠道打包方式有兩種 ,一種是通過gradle打包,還有一種是美團的多渠道打包方案具體詳情見這裡
1、Gradle打包
1.1、在Androidmanifest.xml中新增
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
1.2、在build.gradle中新增
productFlavors {
// 百度
baidu {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu" ]
}
//魅族
meizu {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "meizu"]
}
//搜狗
sougou {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "sougou"]
}
這時候在Android Studio右側的Gradle project工作區中就可以看到在這裡配置的多個渠道了,雙擊相應的選項就能build出相應的渠道包了,assembleRelease是build出所有渠道的Release包,這裡只使用了少量的渠道作為示例。這裡的UMENG_CHANNEL_VALUE需要和meta-data中的value一致才能替換。
1.3、獲取渠道號
public static String getApplicationMetadata(Context context,
String metaDataKey) {
ApplicationInfo info = null;
try {
PackageManager pm = context.getPackageManager();
info = pm.getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
return String.valueOf(info.metaData.get(metaDataKey));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
這裡的metaDataKey自然就是UMENG_CHANNEL了
2、美團多渠道打包方案
2.1、環境配置
由於美團的多渠道打包方案需要依靠指令碼來實現,這裡我用的是python,經試驗指令碼檔案在windows 下用3.6版本和mac下用2.7版本都能完美執行。並且需要安裝openpyxl模組。
2.2、檔案說明
打包的檔案有channels.xlsx 和 package.py
channels.xlsx是一個excel表格裡面第一列是渠道號的id,第二列是渠道號的名稱,第三列是渠道名稱的備註(非必須)
package.py 是一個python指令碼檔案
import datetime
import zipfile
import shutil
import sys
import os
from openpyxl import load_workbook
starttime = datetime.datetime.now()
apk_path = sys.argv[1]
print(os.path.abspath(apk_path))
file_path=os.path.dirname(os.path.abspath(apk_path))+os.path.sep
out_path =file_path+'output'
if not os.path.exists(out_path):
os.makedirs(out_path)
else:
shutil.rmtree(out_path,True)
os.makedirs(out_path)
name = os.path.basename(apk_path)
origin_apk_name = os.path.splitext(name)[0]
wb=load_workbook(filename=file_path+'channels.xlsx',read_only=True)
sheets = wb.get_sheet_names()
ws=wb[sheets[0]]
for row in ws.rows:
idStr=str(row[0].value)
channelStr=str(row[1].value)
channel_apk_name='{}-{}-{}.apk'.format(idStr,channelStr,origin_apk_name)
channel_apk_path=os.path.join(out_path,channel_apk_name)
shutil.copy2(apk_path,channel_apk_path)
zipped=zipfile.ZipFile(channel_apk_path,'a',zipfile.ZIP_DEFLATED)
empty_channel_file="META-INF/channel_{}_{}".format(idStr,channelStr)
zipped.writestr(empty_channel_file, '')
zipped.close()
print(idStr+":"+channelStr)
endtime=datetime.datetime.now()
between=(endtime-starttime).microseconds/1024
print('time:%d ms' % between)
2.3、執行指令碼
在命令列中輸入 python package.py xxxx.apk
如果Python命令是在package.py所在目錄下用上面的方式輸入,也可以將package.py和apk檔案直接拖入命令視窗中執行,然後就會在apk所在路徑下生成一個output資料夾裡面有所有生成的渠道包。
2.4、獲取渠道號
這時候用Android Studio 開啟新生成的渠道包,Build——>Analyze Apk選中剛才生成的apk開啟META-INF資料夾可以看到這樣的的一個檔案channel_{id}_{name}的檔案,由於它是一個空檔案,所以可以看到它的體積大小為0B。因此新的渠道包也不會需要重新簽名。
程式碼中獲取渠道號
public static String[] getChannel() {
ApplicationInfo appinfo = App.getInstance().getContext().getApplicationInfo();
String sourceDir = appinfo.sourceDir;
String ret = "";
ZipFile zipfile = null;
try {
zipfile = new ZipFile(sourceDir);
Enumeration<?> entries = zipfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
if (entryName.startsWith("META-INF/channel")) {
ret = entryName;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
String[] split = ret.split("_");
if (split != null && split.length >= 2) {
for (int i = 0; i < split.length; i++) {
Logger.e(split[i]);
}
return split;
} else {
return null;
}
}
在這裡獲取到的split資訊應該是[“META-INF/channel”,”18”,”uc”],然後獲取自己需要的資訊就好了
3、兩種打包方式對比
打包方式 | 特點 | 優點 | 缺點 | 適用場景 |
---|---|---|---|---|
gradle | productFlavors下配置渠道號,assembleRelease一鍵執行打完所有包 | 配置簡單 | 每個包都需要重新build,耗時較長 | 渠道包較少時 |
美團多渠道打包方案 | 通過指令碼檔案在apk的META-INF目錄下生成包含渠道號的空檔案 | 打包速度快 | 需要依賴外部的指令碼檔案來實現,修改指令碼有學習成本 | 渠道包比較多時 |
4、遇到的其他問題
4.1、umeng的渠道號設定
這種方式不會替換meta-data中的資訊,好在umeng提供了在程式碼中設定channel的方法,詳情見這裡
4.2、注意事項
渠道包的位置一定要和channel的配置檔案在同一目錄下
4.3、打包方式優化
這種方式還是需要自己輸入命令列,稍後打算寫一份.bat檔案讓他雙擊執行。
打包指令碼下載
轉載請註明出處:http://blog.csdn.net/zhong1113/article/details/54094770