日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android批量打包 如何一秒内打完几百个apk渠道包

發布時間:2024/4/17 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android批量打包 如何一秒内打完几百个apk渠道包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在國內Android常用渠道可能多達幾十個,如:?
谷歌市場、騰訊應用寶、百度手機助手、91手機商城、360應用平臺、豌豆莢、安卓市場、小米、魅族商店、oppo手機、聯想樂商、中興匯天地、華為、安智、應用匯、木螞蟻、3G安卓市場(久邦開發者發布系統)?
uc應用商店、蘇寧應用、淘寶手機助手、蘑菇市場、搜狗市場、搜狗助手、機鋒、易用匯(金立手機)、中國聯通沃商、中國移動MM、中國電信天翼、億優市場、歷趣世界、冒泡堂、網訊安卓開發者平臺、桌樂、網易、泡椒網、十字貓、酷傳、安粉、安卓園、安卓之家?
所以在工作中,當項目開發、測試完畢后就需要針對不同的渠道打出對應的apk安裝包。為了統計每個渠道效果,我們可以使用Umeng sdk或者百度的sdk。這些sdk的使用我就不再這里贅述了,請看相應的開發文檔即可。本文以友盟統計為例。

批量打包方式一:Gradle方式

我相信現在應該很多開發環境都是AndroidStudio了,對Gradle相對還是熟悉的。如果您使用的是Eclipse也沒有關系,用AndroidStudio導入Eclipse工程,或者把gradle配置放在Eclipse工程下(因為AndroidStudio和Eclipse的工程目錄有些差別,把對應的目錄配置對即可)?
首先我們使用AndroidStudio新建一個工程,名叫AndroidBatchApk,工程結構如下:?
打開AndroidManifest.xml文件 添加友盟的渠道配置如下:

在MainActivity 顯示渠道名代碼:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String channel = ManifestUtil.getMetaDataFromAppication(this, "UMENG_CHANNEL");//String channel = ManifestUtil.getUmengChannel(this); ((TextView) findViewById(R.id.tv_channel)).setText(channel);} } <meta-dataandroid:name="UMENG_APPKEY"android:value="Your UMENG_APPKEY" /><meta-dataandroid:name="UMENG_CHANNEL"android:value="${UMENG_CHANNEL_VALUE}" /> //${UMENG_CHANNEL_VALUE}是個占位符 打開app目錄下的build.gradle文件,修改成如下形式:

pply plugin: 'com.android.application'android {compileSdkVersion 22buildToolsVersion "22.0.1"packagingOptions {exclude 'META-INF/NOTICE.txt'exclude 'META-INF/LICENSE.txt'}//簽名 signingConfigs {release {//storeFile file("../yourapp.keystore")storeFile file("keystore_apk.jks")storePassword "123456"keyAlias "apk"keyPassword "123456"}}buildTypes {release {// 不顯示Log//buildConfigField "boolean", "LOG_DEBUG", "false"//minifyEnabled true //混淆zipAlignEnabled true //內存對齊shrinkResources true //移除無用的resource文件proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'signingConfig signingConfigs.releaseandroid.applicationVariants.all { variant ->def stringsFile = new File(variant.outputs[0].processResources.assetsDir, "abc.txt")stringsFile.mkdir()}applicationVariants.all { variant ->variant.outputs.each { output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {def fileName = "APK_${releaseTime()}_${variant.productFlavors[0].name}.apk"output.outputFile = new File(outputFile.parent, fileName)}}}}}lintOptions {checkReleaseBuilds falseabortOnError falseignoreWarnings true}// 渠道列表 productFlavors {_360 {}_91 {}QQ {}appChina {}baidu {}google {}//..... }productFlavors.all { flavor ->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]}}def releaseTime() {return new Date().format("yyyy-MM-dd HH-mm-ss", TimeZone.getTimeZone("GMT+8"))}dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])compile 'com.android.support:appcompat-v7:22.2.1'}

上面的配置,我們測試打6個包,分別是google 、_360、 _91、 appChina、 QQ、 baidu

打開cmd命令行 進入工程所在的目錄,輸入命令:gradle build 不出意外將看到如下成功界面:?

并且在output目錄下生成了我們要的apk包(AndroidBatchApk\app\build\outputs\apk)?

現在用的安裝我們的生成apk文件,安裝google渠道的apk。?

到這里我們就通過gradle方式成功的批量打包了,

時間我們只花費了25秒,但是這是最簡單的工程,如果是實際的開發中,我們的項目會很大,打包的時間也會花費很長時間,我現在公司的項目,通過這種方式打包,需要30、40分鐘左右,這也是挺長的。時間上并不占優勢。但是比我們用工具一個個的打apk強太多了。下面為大家界面一種更高效的打包方式。

批量打包方式二:Python批量打包

首先配置好Python,我用的是Python2.7版本。使用該方式,不把渠道名稱放在AndroidManifest.xml 里,而是新建一個空文件,文件名就是渠道名稱。該文件放在apk目錄的META-INF里。META-INF目錄下默認文件列表如下:?

現在我們要解決兩個問題:

如果在META-INF目錄下新建文件?

我們解決第一個問題。首先我們通過AndroidStudio或者Eclipse打一個正式環境的apk安裝包,不需要有渠道。?
然后按照渠道列表 復制出各個渠道的,然后往apk文件里寫入文件為渠道名的空文件。我們使用Python代碼來實現該功能,代碼如下:

import sys,os,shutil,zipfile,time apkVersion="1.0" srcFileName="source.apk" destDir=os.path.abspath('.') file=open("channel.txt")def writeChannelToApk(filename,channel):z=zipfile.ZipFile(filename,'a',zipfile.ZIP_DEFLATED)empty_channel_file="META-INF/channel_{channe}".format(channe=channel)target_file="channel.apk"z.write(target_file,empty_channel_file)z.close()print "writeChannelToApkchannel"+channel+","+filename+"\n"def cpFile(srcPath,fileName):destPath = destDir + os.path.sep + fileNameif os.path.exists(srcPath) and not os.path.exists(destPath):shutil.copy(srcPath,destPath)if not os.path.exists(srcFileName):print "sourcefile"+srcFileName+"notexists"sys.exit(1)start = time.clock()for line in file:channel=line.strip('\n').strip()targetFileName="apk_"+channel+"-"+apkVersion+".apk"print "copyfile:"+targetFileNamecpFile(srcFileName,targetFileName)writeChannelToApk(targetFileName,channel) end = time.clock()print("The function run time is : %.03f seconds" %(end-start))

上面是我編寫的Python代碼,根據代碼我們需要三個文件,一個我們打出的apk文件(source.apk 當然名字可以改)、一個空apk文件(channel.apk)和渠道列表文件(channel.txt) 目錄如下:?

渠道文件內容如下:?
360?
appChina?
wandoujia?
91?
baidu?
QQ?
3G?
eoe?
anzhi?
163?
hiapk?
jifeng?
xiaomi?
meizu?
oppo?
lenovo

在命令行輸入:python batch_apk.py 回車

瞬間完成:?

解壓文件oppo渠道的apk,看看是不是META-INF下是不是有渠道文件:?

如果讀取META-INF下的渠道文件?

public class ManifestUtil {public static String channel;public static String getUmengChannel(Context context) {//return getMetaDataFromAppication(context, "UMENG_CHANNEL");return getChannel(context);}/*** 獲取META-INFO下面的渠道* @param context* @return*/public static String getChannel(Context context) {if (!TextUtils.isEmpty(channel)) {return channel;}ApplicationInfo appinfo = context.getApplicationInfo();String sourceDir = appinfo.sourceDir;ZipFile zipfile = null;final String start_flag = "META-INF/channel_";try {zipfile = new ZipFile(sourceDir);Enumeration<?> entries = zipfile.entries();while (entries.hasMoreElements()) {ZipEntry entry = ((ZipEntry) entries.nextElement());String entryName = entry.getName();if (entryName.contains(start_flag)) {channel = entryName.replaceAll(start_flag, "");return channel;}}} catch (IOException e) {e.printStackTrace();} finally {if (zipfile != null) {try {zipfile.close();} catch (IOException e) {e.printStackTrace();}}}return "";} }

我們安裝oppo渠道的apk看看能否讀取到渠道名:?

通過上面的對比,使用Pyhon往META-INF寫入渠道的方式,比gradle方式極大的提高了效率。

資源下載

腳本地址Github

Have Fun !


2017-07-06更新

由于Android7.0的版本上不能安裝app,提示?INSTALL_PARSE_FAILED_NO_CERTIFICATES?可以使用美團開源的工具:?
打包工具

?

轉載于:https://www.cnblogs.com/zhujiabin/p/7690942.html

總結

以上是生活随笔為你收集整理的Android批量打包 如何一秒内打完几百个apk渠道包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜天堂网 | 欧美在线视频a | 先锋影音av资源在线观看 | 亚洲免费视频一区二区 | 日韩国产精品视频 | 国产伦精品一区二区三区四区视频 | 91精品免费看 | 国产绳艺sm调教室论坛 | 亚洲自拍偷拍综合 | av免费久久 | 亚洲激情黄色 | 欧美视频 | 久久精品国产大片免费观看 | 精品一区二区三区精华液 | 亚洲中文字幕无码一区 | 亚洲免费一区二区 | 性欧美lx╳lx╳ | 欧美一级二级片 | 骚虎视频在线观看 | 成人片免费视频 | 久久亚洲影视 | 欧美人性生活视频 | 欧美视频不卡 | 无码熟妇αⅴ人妻又粗又大 | 啪啪资源 | 国产精品久久久久久久久岛 | 日韩一区二区三区在线视频 | 国产在线精品观看 | 成人免费影片 | 国产乱淫a∨片免费视频 | 在线观看午夜视频 | 日本亚洲欧洲色 | 久久爱影视i | 最新的黄色网址 | 亚洲啊啊| 一本色道久久hezyo加勒比 | 亚洲色图第1页 | 欧美一区亚洲一区 | 欧美肥老妇视频九色 | 男女国产视频 | 粗大的内捧猛烈进出 | 在线欧美国产 | 自拍99页| 又色又爽又黄18网站 | 九热在线| 午夜免费激情视频 | 黄色污污视频网站 | 五月天精品视频 | 国产日韩精品一区 | 亚洲成年 | 欧美性猛交bbbbb精品 | 黄色中文字幕 | 丁香色欲久久久久久综合网 | 深夜精品视频 | 性欧美18一19内谢 | 国产又粗又猛又黄又爽无遮挡 | 欧美亚洲中文精品字幕 | 老熟女高潮一区二区三区 | 久草蜜桃 | 黄色1级视频 | 无码视频一区二区三区 | 久久久久无码精品国产sm果冻 | 一个人在线观看免费视频www | 四虎啪啪| 中文字幕成人在线观看 | 亚洲一区二区三区不卡视频 | 成人免费视频毛片 | 亚洲精品合集 | av资源在线播放 | av在线激情 | 国产精品电影 | 麻豆精品 | 日韩精品一级 | 男女一进一出视频 | jul023被夫上司连续侵犯 | 女人18毛片水真多 | 国产伦精品一区二区三区照片91 | 亚洲av无码乱码国产麻豆 | 国产在线日韩 | 香蕉成人在线视频 | 精品亚洲国产成av人片传媒 | jizz视频在线观看 | 亚洲欧洲精品一区二区 | 中文字幕在线不卡 | 亚洲精品久久一区二区三区777 | 亚洲高清色 | 中文字幕乱码一区 | 日韩美女视频在线观看 | 大咪咪av| 亚洲一区二区视频网站 | 羞视频在线观看 | 97在线播放免费观看 | 国产精品欧美一区二区 | 成年人性生活免费视频 | 无码人妻精品一区二区三应用大全 | 亚洲综合在线视频 | 亚洲成人黄色小说 | 色婷婷婷| 美女黄色真播 |