南京比较大的外贸公司有哪些/系统优化的方法
目录
- 1.添加productFlavors的配置
- buildConfigField
- manifestPlaceholders
- resValue
- 2.设置apk文件的名称,便于识别
- 3.添加vasdolly、添加gradle脚本(windows)
作用:一次性可以打多个apk包,名字、包名、logo等可以不相同。解决了每次发版都要手动修改代码的问题,例如:名字、logo等。
配置build.gradle(app)
1.添加productFlavors的配置
android{.....
//设置风味的维度flavorDimensions = ["release"]//productFlavors中有两套配置,huawei、oppo。productFlavors {huawei {versionCode 8versionName "1.7.33"dimension "release"applicationId "test.test.abc"resValue "string", "file_provider_name_personal", applicationId + ".provider"manifestPlaceholders = [apkName: '语文',apkIcon: '@drawable/yuwen']ndk {abiFilters "arm64-v8a"//"armeabi-v7a" , "arm64-v8a"}buildConfigField "int", "COMPANY", "1"}oppo {versionCode 7versionName "1.6.30"dimension "release"applicationId "test.test.abc"resValue "string", "file_provider_name_personal", applicationId + ".provider"manifestPlaceholders = [apkName: '数学',apkIcon: '@drawable/yuwen']ndk {abiFilters "arm64-v8a"//"armeabi-v7a" , "arm64-v8a"}buildConfigField "int", "COMPANY", "4"}}
}
buildConfigField "int", "COMPANY", "1"
buildConfigField
buildConfigField申明了一个常量,方便在代码中进行使用。
BuildConfig文件:
public final class BuildConfig {public static final int COMPANY = 1;
}
使用buildConfigField
public class MyApplication extends Application {@Overridepublic void onCreate() {Constant.URL_PROTOCOLUSE = "http://xxx.xxx.cn/api/pro.jsp?company=" + BuildConfig.COMPANY + "&apptype=" + getString(R.string.app_name);}
}
manifestPlaceholders
设置在manifest中数据
manifestPlaceholders = [apkName: '数学',apkIcon: '@drawable/yuwen']
<applicationandroid:name=".MainApplication"android:allowBackup="false"android:icon="${apkIcon}"android:label="${apkName}"></application>
resValue
声明一个在Strings.xml中的字符串。
resValue "string", "file_provider_name_personal", applicationId + ".provider"
声明后,会自动生成。
<?xml version="1.0" encoding="utf-8"?>
<resources><!-- Automatically generated file. DO NOT MODIFY --><string name="file_provider_name_personal" translatable="false">test.test.abc</string></resources>
2.设置apk文件的名称,便于识别
static def releaseTime() {SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");return formatter.format(new Date())
}
android {....applicationVariants.all { variant ->variant.outputs.all { output ->def outputFile = output.outputFiledef fileNameif (outputFile != null && outputFile.name.endsWith('.apk')) {if (variant.buildType.name.equals('release')) {//如果是release包fileName = "${productFlavors.name}-${buildType.name}-${productFlavors.versionName}-" +"${productFlavors.versionCode}-${releaseTime()}.apk"} else if (variant.buildType.name.equals('debug')) {//如果是debug包fileName = "${productFlavors.name}-${buildType.name}-${productFlavors.versionName}-" +"${productFlavors.versionCode}.apk"}outputFileName = fileName}}}
}
打出的apk,名字-包类型-版本名称-版本号
一次性打多个包,使用assemble
assemble执行完毕后,在app/build/outputs/apk中寻找。大致样子如下
3.添加vasdolly、添加gradle脚本(windows)
vasdolly使用
https://github.com/Tencent/VasDolly
在build.gradle(app)文件中加入如下
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def sdkDir = properties.getProperty("sdk.dir")
def buildToolsVersion = '33.0.1'//工具版本
def consolidatePath = "./build/consolidate/"
def storePwd = " "//keystore文件密码
def alias = " "//keystore文件alias
def keyPwd = " "//keystore文件密码def jksPath = "C:\\Users\\xxx\\Desktop\\资料\\app.keystore"//keystore文件路径
/*** 优化加签名*/
task batchSign {doLast {File consolidateDir = new File(project.buildDir, "consolidate/")consolidateDir.eachFile { apkFile ->def unsignedFileName = apkFile.getName()def lastchar = unsignedFileName.indexOf(".apk")def fileName = unsignedFileName.substring(0, lastchar)def zipalignedFileName = "${fileName}_zipaligned.apk"def signedFileName = "${fileName}_signed.apk"def buildToolsPath = "${sdkDir}\\build-tools\\${buildToolsVersion}"def command = "${buildToolsPath}\\zipalign -f -p 4 ${consolidatePath}${unsignedFileName} ${consolidatePath}${zipalignedFileName} && " +"del ${project.buildDir}\\consolidate\\${unsignedFileName} && " +"${buildToolsPath}\\apksigner sign --ks ${jksPath} --ks-pass " +"pass:${storePwd} --ks-key-alias ${alias} --key-pass pass:${keyPwd} --out " +"${consolidatePath}${signedFileName} ${consolidatePath}${zipalignedFileName} && " +"del ${project.buildDir}\\consolidate\\${zipalignedFileName} && " +"del ${project.buildDir}\\consolidate\\${fileName}_signed.apk.idsig"println(command)exec {ExecSpec execSpec ->executable 'cmd'args '/c', command}}}
}
/*
将apk优化和签名后,添加渠道
打渠道包*/
task makeChannel {def publishPath = "./build/publish/"doLast {def channels = "./channels.txt" //vasdolly的相关文件File consolidateDir = new File(project.buildDir, "consolidate/")consolidateDir.eachFile { apkFile ->def command = "java -jar D:\\android\\gitdown\\VasDolly.jar put -c ${channels} ${apkFile.getAbsolutePath()} ${publishPath}"try {exec {commandLine 'cmd', '/c', command}} catch (Exception e) {e.printStackTrace()}}}
}
task bundleAndChannel {dependsOn(batchSign)dependsOn(makeChannel)
}
编译之后面,在gradle中就会出现bundleAndChannel
准备加固、签名、渠道
在app/build/目录下,创建consolidate和publish文件。
将360加固后的apk,复制到app/build/consolidate文件中。
双击bundleAndChannel ,等待编辑,就可以了。
相关文章:

Android 多渠道打包及VasDolly使用
目录 1.添加productFlavors的配置buildConfigFieldmanifestPlaceholdersresValue 2.设置apk文件的名称,便于识别3.添加vasdolly、添加gradle脚本(windows) 作用:一次性可以打多个apk包,名字、包名、logo等可以不相同。…...

LeetCode 42题:接雨水
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,…...

spring boot 提示:程序包不存在,解决方法总结
背景: 之前出现过这样的问题,打包安装父项目就好了,今天改了一下代码,重新编译的时候,又出现了这样的情况,决定深度挖掘一下这里面的问题 spring boot 提示:程序包不存在,解决方法总…...

docker项目实战
1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘 1)拉取mysql:5.6和owncloud镜像 [rootmaster ~]# docker pull mysql:5.6 5.6: Pulling from library/mysql 35b2232c987e: Pull complete fc55c00e48f2: Pull complete 0030405130e3: Pull compl…...

银行客户关系管理系统springboot财务金融进销存java jsp源代码
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 银行客户关系管理系统springboot 系统有1权限&#x…...

Maven 插件 maven-antrun-plugin 执行 ant 脚本
Ant 相信大家都不陌生,你可以把它理解为使用 xml 格式描述的一系列命令处理工具。它是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make、有些类似于基于shell命令编写的sh脚本文件。Ant 用 Java 的类来扩展。&a…...

【仿写框架之仿写Tomact】四、封装HttpRequest对象(属性映射http请求报文)、HttpResponse对象(属性映射http响应报文)
文章目录 1、创建HttpRequest对象2、创建HttpResponse对象 1、创建HttpRequest对象 HttpRequest对象中的属性与HTTP协议中的内容对应,用于后序servlet从request中获取请求中的参数。 参照http请求报文: import java.io.BufferedReader; import java…...

LeetCode 41题:缺失的第一个正数
目录 题目 思路 代码 题目 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1: 输入:nums [1,2,0] 输出:3示例 2ÿ…...

学单片机有什么用?
单片机简而言之就是一个小计算机系统,它已经应用到了我们生活中的方方面面。单片机比专用处理器适合应用于嵌入式系统,因此它得到了多的应用,事实上单片机是世界上数量多的计算机。 现代人类生活中所用的几乎每件电子和机械产品中都会集成有单…...

Go 1.21新增的 slices 包详解(二)
Go 1.21新增的 slices 包提供了很多和切片相关的函数,可以用于任何类型的切片。 slices.Delete 定义如下: func Delete[S ~[]E, E any](s S, i, j int) S 从 s 中删除元素 s[i:j],返回修改后的切片。如果 s[i:j] 不是 s 的有效切片&#…...

解决charles无法抓取localhost数据包
我们有时候在本地调试的时候,使用charles抓取向本地服务发送的请求的,发现无法抓取。 charles官方也作了相应说明: 大概意思就是 某些系统使用的是硬编码不能使用localhost进行传输,所以当我们连接到 localhost的时候,…...

基于注解优雅的实现接口幂等性
一、什么是幂等性 简单来说,就是对一个接口执行重复的多次请求,与一次请求所产生的结果是相同的,听起来非常容易理解,但要真正的在系统中要始终保持这个目标,是需要很严谨的设计的,在实际的生产环境下&…...

flutter:webview_flutter和flutter_inappwebview的简单使用
前言 最近在研究如何在应用程序中嵌入Web视图,发现有两个库不错。 一个是官方维护、一个是第三方维护。因为没说特别的需求,就使用了官方库,实现一些简单功能是完全ok的 webview_flutter 不建议使用,因为效果不怎么样…...

opencv进阶09-视频处理cv2.VideoCapture示例(打开本机电脑摄像头)
视频信号(以下简称为视频)是非常重要的视觉信息来源,它是视觉处理过程中经常要处理的一类信号。实际上,视频是由一系列图像构成的,这一系列图像被称为帧,帧是以固定的时间间隔从视频中获取的。获取…...

大语言模型与语义搜索;钉钉个人版启动内测,提供多项AI服务
🦉 AI新闻 🚀 钉钉个人版启动内测,提供多项AI服务 摘要:钉钉个人版正式开始内测,面向小团队、个人用户、高校大学生等人群。该版本具有AI为核心的功能,包括文生文AI、文生图AI和角色化对话等。用户可通过…...

小程序-基于vant的Picker组件实现省市区选择
一、原因 因vant/area-data部分的市/区数据跟后台使用的高德/腾讯省市区有所出入,故须保持跟后台用同一份数据,所以考虑以下几个组件 1、Area 2、Cascader 3、Picker 因为使用的是高德地图的省市区json文件,用area的话修改结构代价太大&…...

智慧水利利用4G物联网技术实现远程监测、控制、管理
智慧水利工业路由器是集合数据采集、实时监控、远程管理的4G物联网通讯设备,能够让传统水利系统实现智能化的实时监控和远程管理。工业路由器利用4G无线网络技术,能够实时传输数据和终端信息,为水利系统的运维提供有效的支持。 智慧水利系统是…...

sql server Varchar转换为Datetime
将Varchar转换为Datetime是一个常见的需求,在处理日期和时间数据时特别有用。在SQL Server中,可以使用CONVERT函数或CAST函数将Varchar转换为Datetime。 使用CONVERT函数 CONVERT函数可以将一个值从一个类型转换为另一个类型。以下是使用CONVERT函数将…...

什么文件传输协议才能保障跨国文件传输安全又稳定
在当今的全球化时代,跨国文件传输是一种常见而又重要的需求,无论是个人还是企业,都需要通过网络来分享和交换各种类型和大小的文件。但是,跨国文件传输也面临着许多挑战和风险,如何选择一个合适的文件传输协议…...

LeetCode笔记:Weekly Contest 359
LeetCode笔记:Weekly Contest 359 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接:https://leetcode.com/contest/weekly-contest-359 1. 题目一 …...

使用Java和ChatGPT Api来创建自己的大模型聊天机器人
文章目录 前言ChatGPT Api简析Chatfunction call Embeddings 制作机器人上下文向量数据库 更多场景介绍扩展阅读 前言 什么是大模型? 大型语言模型(LLM)是一种深度学习模型,它使用大量数据进行预训练,并能够通过提示工…...

Maven介绍_下载_安装_使用_原理
文章目录 1 Maven介绍1.1 Maven是介绍1.2 Maven的作用 2 Maven下载与安装2.1 官网下载2.2 文件目录2.3 环境配置 3 Maven基础概念3.1 仓库分类3.2 依赖坐标3.3 坐标组成 4 Maven配置4.1 本地仓库配置4.2 远程仓库的设置4.3 镜像仓库配置4.4 IDEA配置Maven 5 Maven项目创建5.1 M…...

算法通关村十一关 | 位运算的规则
1.数字在计算机中的表示 机器数:一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是自带符号的,在计算机用一个数的最高位存放符号,整数为0,负数为1。比如,十进制中的数3,计算机字…...

【Rust】Rust学习 第十五章智能指针
指针 (pointer)是一个包含内存地址的变量的通用概念。这个地址引用,或 “指向”(points at)一些其他数据。Rust 中最常见的指针是第四章介绍的 引用(reference)。引用以 & 符号为标志并借用…...

炒股怎样加杠杆?关于股票杠杠平台比例的选择知识分析
在股票市场中,加杠杆是一种常见的投资策略,可以帮助投资者提升收益,但也伴随着更高的风险。本文将介绍炒股加杠杆的具体步骤和股票杠杆平台比例选择的知识分析,帮助读者更好地了解并使用这一策略。 一、炒股加杠杆的步骤 1. 选择…...

【jenkins】jenkins流水线构建打包jar,生成docker镜像,重启docker服务的过程,在jenkins上一键完成,实现提交代码自动构建的功能
【jenkins】jenkins流水线构建打包jar,生成docker镜像,重启docker服务的过程,在jenkins上一键完成,实现提交代码自动构建,服务重启,服务发布的功能。一键实现。非常的舒服。 1. 启动脚本 shell脚本 这是 s…...

Pytest使用fixture实现token共享
同学们在做pytest接口自动化时,会遇到一个场景就是不同的测试用例需要有一个登录的前置步骤,登录完成后会获取到token,用于之后的代码中。首先我先演示一个常规的做法。 首先在conftest定义一个login的方法,方法返回token pytes…...

You have docker-compose v1 installed, but we require Docker Compose v2.
curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version...

nlopt在windows上的安装使用
nlopt在windows上的安装使用 目录 nlopt在windows上的安装使用一、nlopt下载二、def转lib三、代码 一、nlopt下载 1.下载nlopt库:https://nlopt.readthedocs.io/en/latest/ 2.解压 3.下载dll和def:http://ab-initio.mit.edu/wiki/index.php?titleNLopt…...

【React学习】React中的setState方法
1. setState概述 setState 是React框架中,用于更新组件状态的方法。 setState 方法由React组件继承自 React.Component 类的一部分。通过调用 setState,可以告诉 React要更新组件的状态,并触发组件的重新渲染。 this.setState(newState, ca…...