跳至主要内容

Android 自动打渠道包工具(walle+自动化)

AutomaticPackagingTool

Android 自动打渠道包工具,使用 python 3.7 使用之前必须安装并配置相关环境(Java、Android、Python)

自动化打包操作流程

1. 在 Android 项目的根目录 build.gradle 文件中添加 Walle Gradle 插件的依赖, 如下:

buildscript {
    dependencies {
        classpath 'com.meituan.android.walle:plugin:1.1.6'
    }
}
当前 app 的 build.gradle 文件中 apply 这个插件,并添加上用于读取渠道号的AAR
apply plugin: 'walle'

dependencies {
    implementation 'com.meituan.android.walle:library:1.1.6'
}
通过以下代码获取渠道信息
String channel = WalleChannelReader.getChannel(this.getApplicationContext());

2. 打一个签名的apk

3. 将项目中的 jks 文件、channel 文件(如果没有请新建一个)、打包好的 apk 文件拷贝到 apk 目录里面

4. 在 python 中配置信息

# android_build_tools 路径
android_build_tools_path = 'D:/DevelopmentTools/Android/SDK/build-tools/28.0.0/'
# 生成的文件名
target_file_name = 'AP'
# jks keystore_password
keystore_password = "123456"
# jks 别名
key_alias = "AutomaticPackaging"
# jks key_password
key_password = "123456"

5. 在 include 文件夹中 run 一下就开始批量打包了

Android 代码:Android source
python 打包工具:AutomaticPackagingTool

手动打包操作流程

1. 对齐:
Win:zipalign -v 4 source.apk destination.apk

Mac:./zipalign -v 4 source.apk destination.apk
2. 优化:
Win:zipalign -c -v 4 destination.apk

Mac:./zipalign -c -v 4 destination.apk

3. 签名

Windows: apksigner sign --ks [你的签名文件] [apk路径]

Mac: apksigner sign --ks [你的签名文件] [apk路径]

4. 检查是否使用v2签名:

java -jar CheckAndroidV2Signature.jar destination.apk
{"ret":0,"msg":"ok","isV2":true,"isV2OK":true} 是 V2 签名的App
{"ret":0,"msg":"ok","isV2":false,"isV2OK":false} 不是 V2 签名的App

5. 写入渠道包信息:

java -jar [刚下载walle-cli-all.jar的路径] batch -f [项目里channel的路径]  [apk路径]

6. 获取渠道信息

String channel = WalleChannelReader.getChannel(context);
转载请注明出处

评论

此博客中的热门博文

MediaStore.Images.保存图片时生成两张图片的问题 并且在oppo手机上时间是1970-01-01 08:00:00

MediaStore.Images.保存图片时生成两张图片的问题 并且在oppo手机上时间是1970-01-01 08:00:00 正确方式如下 使用方式一 private void saveImage( String originFilePath) { File appDir = new File ( Environment . getExternalStorageDirectory() . getPath() + " /leikebaijing/images " ); if ( ! appDir . exists()) appDir . mkdirs(); String fileName; long dateTaken = System . currentTimeMillis(); if (originFilePath . contains( " / " )) { fileName = originFilePath . substring(originFilePath . lastIndexOf( " / " ) + 1 ); } else { fileName = dateTaken + " jpg " ; } File file = new File (appDir, fileName); if ( ! file . exists()) { try { file . createNewFile(); } catch ( IOException e) { e . printStackTrace(); }

虚拟币交易平台 viabtc_exchange_server ubuntu 16.04 安装步骤

########1############ 下载宝塔: wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh Congratulations! Install succeeded! ================================================================== Bt-Panel: http://155.138.211.245:8888/37dfffff username: dbdiyxmj password: f2ec3b83 Warning: If you cannot access the panel, release the following port (8888|888|80|443|20|21) in the security group ================================================================== sudo apt update ########2############ sudo apt install libev-dev libjansson-dev libmpdec-dev libmysqlclient-dev libcurl4-gnutls-dev libldap2-dev libgss-dev librtmp-dev libsasl2-dev git default-jdk openssl libssl-dev mysql-server 数据库root 密码:root ########3############ wget http://www.digip.org/jansson/releases/jansson-2.12.tar.gz tar xzvf jansson-2.12.tar.gz cd jansson-2.12 ./configure --prefix=/usr --disable-static && make && make install  whereis libjansson cd .. ########4#######

泛型中 extends 和 super 的区别?

泛型中 extends 和 super 的区别? <? extends T> 和 <? super T> 是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念 <? extends T>  :是指 上界通配符(Upper Bounds Wildcards) <? super T>  :是指 下界通配符(Lower Bounds Wildcards) 为什么要用通配符和边界? 使用泛型的过程中,经常出现一种很别扭的情况。比如按照题主的例子,我们有Fruit类,和它的派生类Apple类。 class Fruit {} class Apple extends Fruit {} 然后有一个最简单的容器:Plate类。盘子里可以放一个泛型的“东西”。我们可以对这个东西做最简单的“放”和“取”的动作:set( )和get( )方法。 public class Plate <T> { private T item; public Plate ( T item ) { this . item = item; } public T getItem () { return item; } public void setItem ( T item ) { this . item = item; } } 现在我定义一个“水果盘子”,逻辑上水果盘子当然可以装苹果。 Plate< Fruit > plate = new Plate< Apple > ( new Apple ()); 但实际上Java编译器不允许这个操作。会报错,“装苹果的盘子”无法转换成“装水果的盘子”。 error: incompatible types: Plate<Apple> cannot be converted to Plate<Fruit> 所以我的尴尬症就犯了。实际上,编译器脑袋里认定的逻辑是这样的: 苹果 IS-A 水果 装苹果的盘子 NOT-IS-A 装水果的盘子 所以,就算容器里装的东西之间有继承关系,但容器之间是没有继承关