关于安卓grovvy开发(一)bugly混淆自动上报

news2024/11/17 21:33:16

背景

打包,mapping,上传,这些是不是都困扰了开发很多。苦于复制粘贴?反正我是。于是,有了这个

最终效果

请添加图片描述
最终的效果,就是点击项目的打包gradle,复制mapping文件且进行bugly混淆的自动上报。

环境

win10
gradle7.5
jdk8,jdk11
as2022+

特别说明

jdk是要有jdk8和jdk11的。因为bugly的上报jar包,只能用jdk8运行。
在这里插入图片描述
上图是bugly符号表上传的官方说明,已经两年没更新了,可能已经稳定了吧,反正只能用jdk8。
对于上传符号表不懂的朋友,可以看我这篇文章。
https://blog.csdn.net/motosheep/article/details/130398365

开始编码

首先,写grovvy类似的脚本,需要有一定的java基础。这里就不在太多细节上面叙述了,麻烦自行研究。
这里主要分为两大块:
(一)mapping文件的复制
(二)mapping文件的上传


开始!!这里由于过于简单,就两个步骤一起讲。
文件复制,来来去去,都是一个流的操作,而在grovvy中,只需要通过Files.copy即可完成操作!方便吧!
核心代码讲完了,可以关网页了。请添加图片描述
好了,言归正传。
首先大致的流程如下:
找到release包生成的mapping目录–>复制mapping文件到自定义的目录–>上传mapping文件到bugly。对于上传,这里我写了一个bat脚本,直接在代码里面调用即可!

!!!注意!!!
自己写的xxx.gradle文件,需要放到项目的根目录。然后,需要在app项目中的build.gradle文件使用指令:apply from: "…/copyFileBat.gradle"进行引入,然后愉快地编写task即可。

这里要注意,我们是执行完 assembleRelease 才去进行复制上传的。通过百度网上的代码,可谓是五花八门,最后经过不断尝试,终于跑通了,下面放出代码,目的只有一个,就是要后人,少走弯路!

/**
 * 在打完正式包后执行(assembleRelease)
 */
project.tasks.whenTaskAdded { Task task ->
    if (task.name == 'assembleRelease') {
        task.doLast {
           //todo 操作
        }
    }
}

我们的复制,上传,就是在todo作用域里面进行编码的。
而复制,就是传入两个文件全路径,进行api调用即可。例如:
a.jpg,b.jpg
Files.copy(new File(a.jpg).toPath(),new File(b.jpg).toPath())
即可实现复制!

而项目中,一般mapping路径如下图:

在这里插入图片描述
好了,源文件路径有了,复制指令有了,自己创建一个目录玩去吧。–就是一些File的api操作而已,不过记得,复制之前,要把父目录创建好,才不会报io错误。

下面放出所有核心代码:

copyFileBat.gradle文件:

import java.nio.file.Files
import java.text.SimpleDateFormat

ext {
    //copyFile
    def CopyFilePath = "${rootProject.rootDir}/copytask/"

    //mapping文件原始目录
    MappingFileOrgPath = "${project.buildDir}/outputs/mapping/release/mapping.txt"
    //mapping复制文件目标目录
    def mappingRadonFile = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "mapping.txt"
    MappingFileRootPath = CopyFilePath + "/mapping/"
    MappingPathName = MappingFileRootPath + mappingRadonFile

    //源apk文件
    ApkSourcePath = "${project.buildDir}/outputs/apk/release/"
    //复制apk目标文件夹
    ApkTargetPath = CopyFilePath + "/release/"

    //!!!!!!!!!!bugly 混淆上传相关,需要按照项目配置!!!!!!!!!!!!!!
    //jdk8运行环境
//    JDK8Path = "D:\\software\\java\\jdk1.8\\bin\\java.exe"
    JDK8Path = "D:\\software\\Java\\jdk1.8.0_211\\bin\\java.exe"
    BuglySymJar = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/buglyqq-upload-symbol.jar"
    BuglySymMappingPath = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/mappingfile"
    BuglyPackageName = "com.example.androidjiaguchannel"
    BuglyKey = "d89bcdce-978b-4485-8ff4-a95b20372ed6"
    BuglyId = "877be21cd4"
    BuglyBat = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/run.bat"
}

/**
 * 查找apk文件
 * @param path
 * @param suffix
 * @return
 */
private static File findApkFile(path, suffix) {
    def dir = new File(path)
    return dir.listFiles().find { it.isFile() && it =~ /.*${suffix}\.apk/ }
}

/**
 * 查找txt文件
 * @param path
 * @param suffix
 * @return
 */
private static File findTxtFile(path, suffix) {
    def dir = new File(path)
    return dir.listFiles().find { it.isFile() && it =~ /.*${suffix}\.txt/ }
}

/**
 * 复制mapping文件
 * */
private static boolean copyMapping(MappingFileOrgPath, MappingFileRootPath, MappingPathName) {
    //复制mapping文件
    System.println("----------------assembleRelease finish----------------")
    try {
        System.println("----------------copy mapping file start---------------")
        def orgMappingFilePath = new File(MappingFileOrgPath)
        def targetMappingPath = new File(MappingFileRootPath)
        targetMappingPath.deleteDir()
        targetMappingPath.mkdirs()
        def targetMappingFilePath = new File(MappingPathName)
        Files.copy(orgMappingFilePath.toPath(), targetMappingFilePath.toPath())
        System.println("----------------copy mapping 目录---------------")
        System.println(targetMappingFilePath.toPath())
    } catch (Exception e) {
        e.printStackTrace()
        System.println("----------------copy mapping error,不再进行后续操作----------------")
        return false
    }
    return true
}

/**
 * 复制apk文件
 * */
private static boolean copyReleaseApk(ApkSourcePath, ApkTargetPath) {
    //复制生成的apk release文件
    try {
        System.println("----------------copy release apk---------------")
        System.println("----------------copy apk file start---------------")
        def findSourceApk = findApkFile(ApkSourcePath, "-release")
        if (findSourceApk == null) {
            System.println("----------------copy apk can‘t find-------------")
            return
        }
        def sourceApkNameFullPath = findSourceApk.toPath().toString()
        def fileNameStartPos = sourceApkNameFullPath.lastIndexOf(File.separator)
        def sourceFileName = "app-release.apk"
        if (fileNameStartPos != -1) {
            sourceFileName = sourceApkNameFullPath.substring(fileNameStartPos + 1)
        }
        def orgApkFilePath = findSourceApk
        def targetApkPath = new File(ApkTargetPath)
        targetApkPath.deleteDir()
        targetApkPath.mkdirs()
        def targetApkFilePath = new File(ApkTargetPath + sourceFileName)
        Files.copy(orgApkFilePath.toPath(), targetApkFilePath.toPath())
        System.println("----------------copy apk 目录---------------")
        System.println(targetApkFilePath.toPath())
    } catch (Exception e) {
        e.printStackTrace()
        System.println("----------------copy apk error,不再进行后续操作----------------")
        return false
    }
    return true
}

/**
 * bugly mapping上传
 * */
private static void buglyMappingUpload(JDK8Path, BuglyBat, BuglySymMappingPath, MappingFileRootPath,
                                       BuglySymJar, BuglyPackageName, BuglyId, BuglyKey) {
    try {
//复制mapping文件到脚本目录,然后上传到bugly
        def jdk8File = new File(JDK8Path)
        if (!jdk8File.exists()) {
            System.println("----------------mapping上传要求的jdk8环境不存在---------------" + jdk8File.toPath())
            return
        }
        def outsidePath = BuglyBat
        def uploadBatFile = new File(outsidePath)
        if (!uploadBatFile.exists()) {
            System.println("----------------mapping上传脚本不存在---------------")
            return
        }
        def outsideMappingPath = BuglySymMappingPath + "/"
        new File(outsideMappingPath).mkdirs()
        System.println("----------------mapping上传脚本开始---------------")
        def findSourceMappingFile = findTxtFile(MappingFileRootPath, "mapping")
        if (findSourceMappingFile == null) {
            System.println("----------mapping上传错误,源文件不存在----------")
            return
        }
        def orgFileName = "mapping.txt"
        def fileNameStartPos = findSourceMappingFile.toPath().toString().lastIndexOf(File.separator)
        if (fileNameStartPos != -1) {
            orgFileName = findSourceMappingFile.toPath().toString().substring(fileNameStartPos + 1)
        }
        //外部mapping文件
        def outSizeFilePath = outsideMappingPath + orgFileName
        def outsideFile = new File(outSizeFilePath)
        outsideFile.delete()
        Files.copy(findSourceMappingFile.toPath(), outsideFile.toPath())
        System.println("bugly文件路径: " + outsideFile.toPath())
        System.println("脚本路径:" + uploadBatFile.path)
        Process process = Runtime.getRuntime().exec("cmd /c start " + uploadBatFile.path +
                " ${JDK8Path} ${BuglySymJar} " +
                "${BuglyPackageName} ${BuglySymMappingPath} ${outSizeFilePath} ${BuglyId} ${BuglyKey}")
        process.waitFor() // 等待批处理文件执行完成
        int exitCode = process.exitValue() // 获取批处理文件的退出码
        System.out.println("批处理文件执行完成,退出码:" + exitCode)
    } catch (Exception e) {
        e.printStackTrace()
        System.println("mapping上传错误:\n" + e.printStackTrace())
    }
}


/**
 * 在打完正式包后执行(assembleRelease)
 */
project.tasks.whenTaskAdded { Task task ->
    if (task.name == 'assembleRelease') {
        task.doLast {
            //源mapping复制
            if (!copyMapping(MappingFileOrgPath, MappingFileRootPath, MappingPathName)) {
                return
            }
            //源apk复制
            if (!copyReleaseApk(ApkSourcePath, ApkTargetPath)) {
                return
            }
            //bugly mapping 上传
            buglyMappingUpload(JDK8Path, BuglyBat, BuglySymMappingPath, MappingFileRootPath,
                    BuglySymJar, BuglyPackageName, BuglyId, BuglyKey)
        }
    }
}



bat脚本上传文件:

@echo off
CLS
chcp 65001
echo 参数jdk8路径:%1
echo 参数bugly混淆jar路径:%2
echo 参数bugly目标包名:%3
echo 参数bugly混淆文件父目录:%4
echo 参数bugly混淆文件全路径:%5
echo 参数bugly Id:%6
echo 参数bugly Key:%7
echo "------------------------java版本信息------------------------"
%1 -version
echo "------------------------begin------------------------"
echo "------------------------注意!注意!注意!mapping文件需要放在mappingfile目录下------------------------"
echo "------------------------版本号------------------------"
set /p codeInput="请输入app版本号(例如:1.0.0):"
echo 输入app版本号为:%codeInput%

echo "------------------------开始上传------------------------"
%1 -jar %2 -appid %6 -appkey %7 -bundleid %3 -version %codeInput% -platform Android -inputSymbol %4 -inputMapping %5
pause

注意!!!

copyFileBat.gradle文件中:

    //!!!!!!!!!!bugly 混淆上传相关,需要按照项目配置!!!!!!!!!!!!!!
    //jdk8运行环境
//    JDK8Path = "D:\\software\\java\\jdk1.8\\bin\\java.exe"
    JDK8Path = "D:\\software\\Java\\jdk1.8.0_211\\bin\\java.exe"
    BuglySymJar = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/buglyqq-upload-symbol.jar"
    BuglySymMappingPath = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/mappingfile"
    BuglyPackageName = "com.example.androidjiaguchannel"
    BuglyKey = "d89bcdce-978b-4485-8ff4-a95b20372ed6"
    BuglyId = "877be21cd4"
    BuglyBat = new File("${rootProject.rootDir}").parent + "/buglyqq-upload-symbol/run.bat"

需要修改为你电脑,项目中的配置信息。上述涉及到的变量,都要重新定义,你的环境和我的不一样!

最后,附上相关工具类的网址:
bugly符号表:
https://bugly.qq.com/docs/release-notes/release-symboltool/?v=1.0.0

that’s all--------------------------------------------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1001853.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于单片机超声波测距语音播放

一、系统方案 本设计采用52单片机作为主控器,HC-SR04测距,液晶1602显示,按键设置报警阀值,语音报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 uint dist; // 保存超声波模块测量到的结果…

基于SSM的网上医院预约挂号系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Linux 部分IO函数

open、close函数 标准C库IO函数的说明文档在 man 3 open Linux系统IO函数说明文档在man 2 open open()函数打开文件 && errno 例子:目录下没有a.txt那么运行的时候会报错 open创建新文件 本来没有 create.txt 运行完有了 ll可看文…

【LeetCode-中等题】209. 长度最小的子数组

文章目录 题目方法一:滑动窗口:方法二: 题目 方法一:滑动窗口: 参考图解动画:长度最小的子数组 class Solution { //方法一:滑动窗口public int minSubArrayLen(int target, int[] nums) {int n nums.l…

解决jsp/html界面跳转servlet出现404错误的方法

解决jsp/html界面跳转servlet出现404错误的方法 最近在学习黑马项目过程中遇到的问题 问题一: 检查页面的跳转路径和名称拼写是否正确 问题二: tomcat发布项目时所使用的路径名称与项目不同 在idea右上角点击如图圈住的按钮 在deployment中更改出现…

【SpringCloud微服务项目学习-mall4cloud项目(1)】——环境部署,构建与运行

环境部署,构建与运行 mall4cloud项目介绍源码地址 开发环境搭建pom搭建项目运行前端运行 mall4cloud项目介绍 mall4j商城系统 首先介绍一下mall4j,是一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布…

Redis的基本概念与基础用法(1)

在节假日前12306的访问量就会急剧增加,在这种海量用户高并发的情况下就容易出现网站崩溃的情况,造成网站奔溃的罪魁祸首就是关系型数据库,因为关系型数据库有: 性能瓶颈:磁盘IO性能低下扩展瓶颈:数据关系复…

【三维重建】Ubuntu18.04安装COLMAP

Ubuntu18.04安装COLMAP 文章目录 Ubuntu18.04安装COLMAP前言安装COLMAP:安装CUDA, cuDNN安装依赖项安装Ceres优化库安装glog(可选)配置并编译COLMAP运行COLMAP 总结 前言 COLMAP是一种通用的运动结构(SfM)和多视图立体(MVS)管道,具有图形和命令行界面。…

RBTree(红黑树)模拟实现(插入)

目录 红黑树的性质 红黑树的模拟插入 叔叔存在且为红色 叔叔不存在 旋转情况​​​​​​​ 叔叔存在且为黑色 总结 插入实现 节点 插入逻辑 左单旋 右单旋 红黑树是一颗平衡搜索二叉树,但是红黑树并不像 AVL 树一样是高度平衡二叉树,任意一…

正在吞食世界的Python!

谁能想到,30年后,一条蟒蛇因为人工智能而席卷了全世界!这一切,都源于1989年的那个圣诞节。 一个名叫Guido van Rossum程序员在荷兰的阿姆斯特丹呆着,无所事事的圣诞假期有点无聊。为了打发时间,他开发了一…

前端中的事件委托

前端小知识 事 件 委 托 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/132819265 【介绍】&#xff1…

MATLAB语言 实验一 MATLAB工作环境熟悉及简单命令的执行

一、 实验名称 MATLAB工作环境熟悉及简单命令的执行 二、 实验目的 熟悉MATLAB的工作环境,学会使用MATLAB进行一些简单的运算。 三、实验内容 MATLAB的启动和退出,熟悉MATLAB的桌面(Desktop),包括菜单&#xff08…

抖音视频批量智能剪辑/智能一键成片功能如何技术开发源头?

抖音seo,视频剪辑,批量发布,账号矩阵管理,无人直播自动询盘锁定客户,想实现以上功能都要有正规的接口权限,这个权限接口已经在前面文章发过。 一、剪辑技术开发 智能剪辑:咱们研发公司自主研发…

初识Vue3

目录 创建实例 Vue3生命周期 响应式基础 为什么要使用 ref? 声明响应式状态 ref()和reactive() toRef()和toRefs() 创建实例 通过对Vue2的学习,我们可以这样在Vue2中创建一个实例: var vm new Vue({// 选项 }) 或者通过Vue全局api…

webrtc-m79-测试peerconnectionserver的webclient-p2p-demo

1 背景 webrtc的代码中有peerconnectionclient和peerconnectionserver的例子,但是没有对应的web端的例子,这里简单的写了一个测试例子,具体如下: 2 具体操作 2.1 操作流程 2.2 测试效果 使用webclient与peerconnectionclient的…

Windows安装MySQL8.0完整教程

很多朋友在安装MySQL的时候,总会遇到各种各样的问题。本文来教你怎样正确安装MySQL。 一、 下载MySQL 如果已经下载好了可以忽略,我下面提供两个版本的下载链接 阿里云盘 夸克云盘 链接:https://pan.quark.cn/s/1894623c2e6a 提取码&…

Go入门教程

什么是Go语言? Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回…

BGP感想

BGP 边界网关协议 属于外部或域间路由协议,距离矢量路由协议。 AS(自治系统),在一个自治系统内运行osfp,is-is,rip,vlan等,实现AS内网络互通。 BGP做什么,为处于不同自治系统(AS)中的路由器之间进行“路由信息通信…

视频推流测试——使用ffmpeg进行推流生成rtsp视频流

在我们完成开发工作之后,需要通过推流的形式来验证能否正确接收视频流,并送入视频检测程序。笔者在这里使用的是业内最为常用的ffmpeg。具体方法如下。 1、安装ffmpeg 访问ffmpeg的官网,地址为https://ffmpeg.org/download.html,按照如下途中来选择下载。 下载完成后,会…

LeetCode(力扣)53. 最大子数组和Python

LeetCode53. 最大子数组和 题目链接代码 题目链接 https://leetcode.cn/problems/maximum-subarray/ 代码 class Solution:def maxSubArray(self, nums: List[int]) -> int:result float(-inf)count 0for i in range(len(nums)):count nums[i]if count > result:res…