android插件自定义之多渠道打包插件(支持微信资源混淆andResGuard)
来源:互联网 发布:怎么选购洗衣机知乎 编辑:程序博客网 时间:2024/05/21 10:01
前言
自定义android studio插件?想想就觉得是一件令人兴奋的事。最近闲来无事决定完善之前的一些代码操作,然后就想到了之前的apk多渠道打包工具,觉得还是太麻烦,何不用插件的形式引入工程自动打包呢。说做就做…
资料整理
1.插件入门:http://blog.csdn.net/sbsujjbcy/article/details/50782830
2.插件进阶:AndroidComponent组件化方案,AndResGuard资源混淆库的插件源码
3.渠道包原理:将渠道打入assets里的文件中,我之前的文章有介绍过此原理的打包工具
简单流程图
ejApkRelease task
1.初始化task
创建EjApkTask继承gradle api的DefaultTask来创建自己的task
public class EjApkTask extends DefaultTask{ def android def buildConfigs = [] EjApkTask(){ description = 'Assemble ej APK' group = 'andChannelApk' outputs.upToDateWhen { false } android = project.extensions.android ... } @TaskAction run(){ ... }}
其中:
group表示在android studio 右侧的gradle任务列表为此task创建一个自己的目录:
会自动将大写转为小写,写法参照AndResGuard原码写的
run方法表示此task运行的方法
创建,并初始化ejApkRelease task
project.afterEvaluate { System.out.println("ejApkRelease is start") def taskName = "resguardRelease" def ejTask = "ejApkRelease" def task = project.task(ejTask, type: EjApkTask) //判断是否存在resguardRelease task if(project.tasks.findByPath(taskName) != null){ System.out.println("ejApkRelease is exit") task.dependsOn "resguardRelease" } else { task.dependsOn "assembleRelease" } }
其中project.afterEvaluate闭包的调用位置实在 项目的settings.gradle构建之后,build.gradle构建之前。
task.dependsOn 表示将此任务task的调用位置放在resguardRelease或者assembleRelease task的后面
2.task逻辑处理
通过api 获取app-release.apk文件位置,获取gradle配置的签名文件,获取渠道文件的路径配置:
//渠道文件配置位置 String channel = project.properties.get("channelFile") buildConfigs.each{ config -> if (config.file == null || !config.file.exists()) { System.out.println("ejApkRelease EjApkTask apk file not exit 1") return } //签名文件 def signConfig = config.signConfig //app-release.apk位置 String path = config.file.getAbsolutePath() System.out.println("path:"+path) InputParam.Builder builder = new InputParam.Builder() .setChannel(channel) .setInputFolder(useFolder(config.file)) .setApkPath(path) .setSignFile(signConfig.storeFile) .setKeypass(signConfig.keyPassword) .setStorealias(signConfig.keyAlias) .setStorepass(signConfig.storePassword) InputParam inputParam = builder.build() Main.gradleRun(inputParam) }
其中:
project.properties.get() 表示获取运行项目(app)目录下的gradle.properties文件里面的配置
解压,修改渠道文件,打包签名
1.解压:
解压方式很简单,通过java自带api实现解压:
@SuppressWarnings("rawtypes") public static HashMap<String, Integer> unZipAPk(String fileName, String filePath) throws IOException { checkDirectory(filePath); ZipFile zipFile = new ZipFile(fileName); Enumeration emu = zipFile.entries(); HashMap<String, Integer> compress = new HashMap<>(); while (emu.hasMoreElements()) { ZipEntry entry = (ZipEntry) emu.nextElement(); if (entry.isDirectory()) { new File(filePath, entry.getName()).mkdirs(); continue; } BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry)); File file = new File(filePath + File.separator + entry.getName()); File parent = file.getParentFile(); if (parent != null && (!parent.exists())) { parent.mkdirs(); } //要用linux的斜杠 String compatibaleresult = entry.getName(); if (compatibaleresult.contains("\\")) { compatibaleresult = compatibaleresult.replace("\\", "/"); } compress.put(compatibaleresult, entry.getMethod()); FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER); byte[] buf = new byte[BUFFER]; int len; while ((len = bis.read(buf, 0, BUFFER)) != -1) { fos.write(buf, 0, len); } bos.flush(); bos.close(); bis.close(); } zipFile.close(); return compress; }
1.修改渠道文件:
先删除解压包存在的签名文件,再寻找assets文件夹是否存在,存在直接修改渠道文件,不存在则添加assets文件夹并添加渠道文件,通过渠道文件获取要打的渠道,循环修改,并打包,签名:
public void buildApk() throws Exception { //删除签名文件 File sinFile = new File(tempFile,"META-INF"); if(sinFile.exists()){ FileZipUtils.deleteDir(sinFile); System.out.println("删除原签名文件"); } //存放签名包位置 File fileassets = new File(tempFile,"assets"); if(!fileassets.exists()){ fileassets.mkdirs(); } File fileEjChannel = new File(fileassets,"ej_channel"); if(!fileEjChannel.exists()){ fileEjChannel.createNewFile(); } //打包apk位置 File fileChannel = new File(fileApk,"channel"); if(fileChannel.exists()){ fileChannel.delete(); } File unSinedFiles = new File(fileChannel,"unsign"); File sinedFiles = new File(fileChannel,"sign"); unSinedFiles.mkdirs(); sinedFiles.mkdirs(); File fileChannelTxt = new File(inputParam.channel); if(!fileChannelTxt.exists()){ System.out.println("channel.txt not exit"); return; } //获取所有渠道 InputStream in = new FileInputStream(fileChannelTxt); int size = in.available(); byte[] buffer = new byte[size]; in.read(buffer); in.close(); String allChannel = new String(buffer, "utf-8"); //获取所有渠道数组 String[] channels = allChannel.split(","); //循环渠道打包 for(String content : channels){ { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(fileEjChannel),"UTF-8"); System.out.println("channel content:"+content); //渠道名称加密 String channel = ChannelEncode.encode(content); //不加密// String channel = content; System.out.println("channel:"+channel); osw.write(channel, 0, channel.length()); osw.flush(); osw.close(); //压缩文件 File outApkUnsin = new File(unSinedFiles,"release-"+content+"-unsin.apk"); FileZipUtils.compress(tempFile,outApkUnsin); //签名 File outApkSign = new File(sinedFiles,"release-"+content+"-sin.apk"); signWithV1sign(outApkUnsin,outApkSign); } } }
使用方法
最后讲一下使用方式,由于本插件没有上传jcenter,所以需要下载下来编译一下,编译方式:
通过双击图中的uploadArchives 任务,会在项目的根目录创建本地maven仓库repo
再在项目中引入此插件即可
这是编译通过之后会在右侧出现:
任务,点击运行此任务即可打出渠道包
项目地址https://github.com/dengzhi00/EjApkChannelPlugin
觉得还行就看看吧
- android插件自定义之多渠道打包插件(支持微信资源混淆andResGuard)
- 微信资源混淆AndResGuard原理
- 微信Android资源混淆打包工具
- 微信开源工具AndResGuard做Android资源混淆
- AndResGuard资源混淆工具
- 资源混淆工具AndResGuard
- android之多渠道打包---秒打秒打
- Android studio之多渠道打包
- Mac下使用微信Android资源混淆打包工具
- 使用AndResGuard混淆资源文件
- Android项目集成AndResGuard资源混淆两种方式
- 微信资源混淆工具打包
- Android 分渠道批量打包 常用插件工具
- Gradle之多渠道打包
- 安装包立减1M--微信Android资源混淆打包工具
- 微信Android资源混淆打包工具,如何让应用安装包立减1M
- 安装包立减1M--微信Android资源混淆打包工具
- 安装包立减1M--微信Android资源混淆打包工具
- Linux用户管理详解
- 详解SpringBoot集成jsp(附源码)以及遇到的坑
- 2017/12/15
- 欢迎使用CSDN-markdown编辑器
- 屏蔽kindEditor编辑器编辑图片时自动给图片宽高--解决方案
- android插件自定义之多渠道打包插件(支持微信资源混淆andResGuard)
- 基于Microsoft Visual Studio 2008 的delta3d安装
- php脚本高级分离术
- Cas之5.2.x版本单点登录自定义REST认证-yellowcong
- Sourcetree 使用笔记
- Ubuntu16.04安装maven3.5.2
- 递归专练E 汉诺塔系列之青蛙过河
- Spring中PropertyPlaceholderConfigurer的用法
- 六行代码安装 GPU版本的TensorFlow