v2簽名方案出來前的多渠道生成方案
(1)androidManifest.xml 配置 meta-data
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:name=".MyApplication"
>
...
<meta-data android:value="360" android:name="store_name"/>
</application>
代碼中獲取:
val appInfo = packageManager.getApplicationInfo(
packageName,PackageManager.GET_META_DATA)
//
Log.e("lxm", appInfo.metaData.getString("store_name"))
val activityInfo = packageManager.getActivityInfo(
componentName,PackageManager.GET_META_DATA
)
Log.e("lxm","lxm1 :"+appInfo.metaData.get("store_name"))
Log.e("lxm","lxm2 :"+activityInfo.metaData.getString("store_name"))
效果:
(2)android studio build.gradle下的productFlavors定義渠道號
productFlavors {
//線上的包
dg_online {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "release", BUGLY_APP_VERSION: "1.8.0", BUGLY_APP_CHANNEL: "google play"]
buildConfigField "String", "SERVER_PATH", ""
}
india_online {
}
stock_online {
}
}
優勢:方便靈活,可以根據自身的需求配置不同的渠道執行不同的邏輯;
劣勢:打包速度過慢
(3)META-INF目錄下添加空文件,用空文件的名稱來作爲渠道的唯一標識
v2之前在META-INF下添加文件是不需要重新簽名應用的,這樣會節省不少打包的時間,從而提高打渠道包的速度
實現原理
Android應用安裝包apk文件其實是一個壓縮文件,可以將後綴修改爲zip直接解壓。解壓安裝文件後會發現在根目錄有一個META-INF目錄。如果在META-INF目錄內添加空文件,可以不用重新簽名應用。因此,通過爲不同渠道的應用添加不同的空文件,可以唯一標識一個渠道。這種打包方式,只需要在原來的包的基礎上覆制一個apk,不需要重新簽名,可以實現秒生成渠道包
實現步驟:
準備條件:正常的apk包
(a)在META-INF中添加一個使用渠道號命名的空文件,向META-INF/uuchannel_渠道key 文件夾寫入一個空文件
//部分代碼
empty_channel_file = "META-INF/uuchannel_{channel}".format(channel = target_channel)
zipped.write(src_empty_file, empty_channel_file)
(b)代碼中獲取渠道字段
/**
* 從apk中獲取版本信息
*
* @param context
* @param channelKey
* @return
*/
private static String getChannelFromApk(Context context, String channelKey) {
long startTime = System.currentTimeMillis();
//從apk包中獲取
ApplicationInfo appinfo = context.getApplicationInfo();
String sourceDir = appinfo.sourceDir;
//默認放在meta-inf/裏, 所以需要再拼接一下
String key = "META-INF/" + channelKey;
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(key)) {
ret = entryName;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
String channel = "";
if (!TextUtils.isEmpty(ret)) {
String[] split = ret.split("_");
if (split != null && split.length >= 2) {
channel = ret.substring(split[0].length() + 1);
}
} else {
channel = DEFAULT_CHANNEL;
}
ToastUtils.showLong("lxm channel:"+channel);
return channel;
}
優勢:打包速度很快,很方便;
劣勢:不夠靈活,不能靈活的配置不同的渠道不同的業務邏輯, app讀取效率不是很高。需要初始化zip對象;
(5) Android Apk 動態寫入數據方案
原理:apk(zip)文件的格式
apk 默認情況下沒有comment,所以 comment length的short 兩個字節爲 0,我們需要把這個值修改爲我們的comment的長度,然後把comment追加到後邊
實現步驟:
條件:apk包(a.apk) ,渠道key(360) 或者一組渠道key
(a)判斷apk文件是否 comment內容
默認情況下是沒有comment,先拷貝新的渠道apk文件(和原來apk只是名稱區分a_360.apk)
(b)獲取新增的comment內容: 渠道key 的byte數組
(c)修改apk文件:
apk 最後兩個字節是short ,comment length 是 0,需要重寫實際的長度,先定位到 最後兩個字節,重寫 comment length ,在 write 新增的comment內容
(d)從文件中讀取渠道
效果:
當v2 默認打開時:測試安裝顯示未通過v2簽名認證
對zip動態寫入數據方案詳情見渠道包快速生成方案
下一節介紹v2簽名方案和美團的多渠道打包方案walle