android工程jrr版本怎么改,2018-10-15【Android打包版本号设置方法】

android工程jrr版本怎么改,2018-10-15【Android打包版本号设置方法】

之前没有设置过打包的命名,每次打包都是默认的"app-realease.apk",之后手动修改名字来显示出它是一个新版本。

晚上学习了如何配置打包名称,很简单,修改build.gradle里的代码就行。

详细记录如下:

1、打开app这个directory下的build.gradle

2、定义打包时间:

//时间

def releaseTime() {

returnnewDate().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))

}

3、自定义发布时的版本号(return的返回值可自行修改,例如1.0、2.0):

//版本号

def getVersionName(){

return"2.0"

}

4、自定义打包名称(代码中的XYZ可修改为app名字):

//名称

applicationVariants.all { variant ->

variant.outputs.each { output ->

def outputFile = output.outputFile

def fileName

if(outputFile != null&& outputFile.name.endsWith('.apk')) {

if(variant.buildType.name.equals('release')) {

variant.mergedFlavor.versionName = getVersionName()

fileName = "XYZ_${variant.mergedFlavor.versionName}_release.apk"

} elseif(variant.buildType.name.equals('debug')) {

variant.mergedFlavor.versionName = getVersionName()+"."+releaseTime()

fileName = "XYZ_${variant.mergedFlavor.versionName}_debug.apk"

}

output.outputFile = newFile(outputFile.parent, fileName)

}

}

}

5、build.gradle的完整代码:

apply plugin: 'com.android.application'

//定义时间

def releaseTime() {

returnnewDate().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))

}

//设置发布时的版本号

def getVersionName(){

return"2.0"

}

android {

compileSdkVersion 26

buildToolsVersion "26.0.0"

defaultConfig {

applicationId "***"

minSdkVersion 14

targetSdkVersion 23

versionCode 1

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

buildTypes {

release {

buildConfigField("boolean","API_DEBUG","false")

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

debug {

buildConfigField("boolean","API_DEBUG","true")

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

}

//配置打包名称

applicationVariants.all { variant ->

variant.outputs.each { output ->

def outputFile = output.outputFile

def fileName

if(outputFile != null&& outputFile.name.endsWith('.apk')) {

if(variant.buildType.name.equals('release')) {

variant.mergedFlavor.versionName = getVersionName()

fileName = "XYZ_${variant.mergedFlavor.versionName}_release.apk"

} elseif(variant.buildType.name.equals('debug')) {

variant.mergedFlavor.versionName = getVersionName()+"."+releaseTime()

fileName = "XYZ_${variant.mergedFlavor.versionName}_debug.apk"

}

output.outputFile = newFile(outputFile.parent, fileName)

}

}

}

}

dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {

exclude group: 'com.android.support', module: 'support-annotations'

})

}

今天升级了AS3.1以后,在项目编译的时候发现Gradle中报错了,错误如下:

Error:(60, 0) Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=xiaomiRelease, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.

Open File

经过一番折腾,网上找大牛的解读,弄明白了output.outputFile变成了只读属性,不能再往里面写东西了,以下是3.0之前的配置:

applicationVariants.all { variant ->    //批量修改Apk名字

variant.outputs.each { output ->

def outputFile = output.outputFile

if (outputFile != null && outputFile.name.endsWith('.apk') && 'release'.equals(variant.buildType.name)) {

def fileName = outputFile.name.replace("${variant.flavorName}", "V${defaultConfig.versionName}-${variant.flavorName}")

fileName = fileName.replace('.apk', "-${buildTime()}.apk")

output.outputFile = new File(outputFile.parent, fileName)

}

}

}

下面是经过修改之后3.0里面批量修改APK名字的配置:

applicationVariants.all { variant ->    //批量修改Apk名字

variant.outputs.all { output ->

if (!variant.buildType.isDebuggable()) {

//获取签名的名字 variant.signingConfig.name

//要被替换的源字符串

def sourceFile = "-${variant.flavorName}-${variant.buildType.name}"

//替换的字符串

def replaceFile = "_V${variant.versionName}_${variant.flavorName}_${variant.buildType.name}_${buildTime()}"

outputFileName = output.outputFile.name.replace(sourceFile, replaceFile);

//遗留问题:如何获取当前module的name,如CodeBooke这个名字怎么获取到

}

}

}

问题:对于如何在gradle中获取module的name,还是没有找到相关的方法,希望有知道的大神留言交流。

2、model下build.gradle

import java.text.SimpleDateFormat

applyplugin:'com.android.application'

android{

compileSdkVersion 28

defaultConfig {

applicationId"ma.mhy.sqliteeditorroot"

minSdkVersion15

targetSdkVersion28

versionCode getMyVersionCode()

versionName getMyVersionName()

testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"

}

buildTypes {

release {

minifyEnabledfalse

proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'

}

}

compileOptions {

sourceCompatibilityJavaVersion.VERSION_1_8

targetCompatibilityJavaVersion.VERSION_1_8

}

}

dependencies{

implementation fileTree(dir:'libs',include: ['*.jar'])

}

staticdefgetMyVersionCode() {

returnInteger.parseInt(newSimpleDateFormat("yyMMdd").format(newDate()))

}

staticdefgetMyVersionName() {

return"1.0.6."+"git describe --always".execute().getText().trim()//自动打包命名区分新旧版

}

build.gradle中自动生成版本号

Android Studio中,gradle.build里的设定会覆盖AndroidManifest.xml中的设置。

Gradle中使用的是Groovy语言,这是一种基于JVM的敏捷开发语言,还算是易学易用的。

在项目的build.gradle中,android.defaultConfig里,把versionCode和versionName改成自定义函数getSelfDefinedVersion:

android {    compileSdkVersion23buildToolsVersion"23.0.3"defaultConfig {        applicationId"com.example.xxx"minSdkVersion22targetSdkVersion23versionCode getSelfDefinedVersion("code")        versionName getSelfDefinedVersion("name")    }    buildTypes {        release {            minifyEnabledfalse}    }}

在build.gradle文件底部,统一实现版本号自动生成管理:

defgetSelfDefinedVersion(type) {intaa =1intbb =0Process process ="git rev-list --count HEAD".execute()    process.waitFor()intcccc = process.getText().toInteger()if("code".equals(type)) {        aa *1000000+ bb *10000+ cccc    }elseif("name".equals(type)) {        String today =newDate().format("yyMMdd")        process ="git describe --always".execute()        process.waitFor()        String sha1 = process.getText().trim()"$aa.$bb.$cccc.$today.$sha1"}}

这样虽然比较简陋,但功能是有了。

打包自动版本号与日期

(build.gradle 文件内容,com.android.tools.build:gradle:3.0.0 以下版本)

android{

defaultConfig {...}

自动追加版本号和版本名称

android.applicationVariants.all {

variant->variant.outputs.each {

output-> output.outputFile = new File(output.outputFile.parent,"app_device_v"+defaultConfig.versionName+"_"+new Date().format("yyyy-MM-dd")+"_"+buildType.name+".apk")

}

}

}

如com.android.tools.build:gradle:3.0.0及其以上版本

android{

defaultConfig {...}

//release版本输出包名自动追加版本号和版本名称

applicationVariants.all {

variant ->

variant.outputs.all {

if (buildType.name == 'release'){

outputFileName = "app_v" + defaultConfig.versionName + "_" + new Date().format("yyyy-MM-dd") + "_" + buildType.name + ".apk"

}

}

}

}

android应用程序的版本号Version name可以在android manifest下手动修改,在code中调用api获取该版本号。

项目中的目标是:每编译一次程序都会自动修改版本号,而不需要手动修改,由于中间debug的次数较多,我打算以每次Build时的当前时间作为版本号。

操作步骤:

1. Android工程目录的assets文件夹下新建一文件,命名为version

2. code中通过api获取assets下的文件内容,回显在activity,基础android编程知识,不解释

3. Android.mk 文件中LOCAL_PATH:= $(call my-dir)下紧接着调用shell语句: $(shell date +%Y%m%d%H:%M:%S>$(LOCAL_PATH)/assets/version)

如果项目对版本号或者版本名称有更复杂的需求,可以直接写成shell脚本,再由Android.mk 调用

编译时自动输出当前编译时间到version文件,并打包到apk中,done!

感谢https://my.oschina.net/u/659658/blog/84545

import java.text.SimpleDateFormat

applyplugin:'com.android.application'

//设置发布时的版本号

static def getVersionName() {

int aa =3

int i ="git rev-list --count HEAD".execute().getText().toInteger()//build次数

String today =new Date().format("yyMMdd")

Process process ="git describe --always".execute()

process.waitFor()

String str = process.getText().trim()

return "$aa.$i.$today.$str"//"3.276"+str     //3.1.20181015.内容

// return aa+"."+i+"."+"."+today+"."+str

}

//设置发布时的版本码

static def getVersionCode() {

Process process ="git rev-list --count HEAD".execute()

process.waitFor()

int i = process.getText().toInteger()

return Integer.parseInt(new SimpleDateFormat("yyMMdd").format(new Date()))*10000 +i//今天日期1810150001+次数

}

android {

compileSdkVersion28

defaultConfig {

applicationId"com.hcsoft.storekeeper"

minSdkVersion15

targetSdkVersion28

versionCodegetVersionCode()

versionName getVersionName()

testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"

}

//release版本输出包名自动追加版本号和版本名称

applicationVariants.all {

variant ->

variant.outputs.all {

if (buildType.name =='release'){

outputFileName ="app_v" + defaultConfig.versionName +"_" +new Date().format("yyyy-MM-dd") +"_" + buildType.name +".apk"

}

}

}

buildTypes {

release {

buildConfigField("boolean","API_DEBUG","false")

minifyEnabledfalse

proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'

}

debug {

buildConfigField("boolean","API_DEBUG","true")

minifyEnabledfalse

proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'

}

}

compileOptions {

sourceCompatibility JavaVersion.VERSION_1_8

targetCompatibility JavaVersion.VERSION_1_8

}

}

dependencies{

implementation fileTree(dir:'libs',include: ['*.jar'])

}

原理是获得打包签名文件的生成时间。

/**

* 获得app的打包时间

*

* @return

*/

private String getAppBuildTime() {

String result = "";

try {

ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(),0);

ZipFile zf = new ZipFile(ai.sourceDir);

ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");

long time = ze.getTime();

SimpleDateFormat formatter = (SimpleDateFormat) SimpleDateFormat.getInstance();

formatter.applyPattern("yyyy/MM/dd HH:mm:ss");

result = formatter.format(new java.util.Date(time));

zf.close();

} catch (Exception e) {

}

return result;

}

上述方法貌似在5.0之后不好用,所以现在建议使用Gradle生成打包时间,然后再引用。核心代码如下:

buildTypes {

release {

buildConfigField("String", "releaseTime", "\""+new Date().format("yyyy/MM/dd HH:mm:ss")+"\"")

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

....

}

主要是使用buildConfigField生成打包时间。

然后使用 TextView.setText(BuildConfig.releaseTime);

Read more

前端防范 XSS(跨站脚本攻击)

目录 一、防范措施 1.layui util  核心转义的特殊字符 示例 2.js-xss.js库 安装 1. Node.js 环境(npm/yarn) 2. 浏览器环境 核心 API 基础使用 1. 基础过滤(默认规则) 2. 自定义过滤规则 (1)允许特定标签 (2)允许特定属性 (3)自定义标签处理 (4)自定义属性处理 (5)转义特定字符 常见场景示例 1. 过滤用户输入的评论内容 2. 允许特定富文本标签(如富文本编辑器内容) 注意事项 更多配置 XSS(跨站脚本攻击)是一种常见的网络攻击手段,它允许攻击者将恶意脚本注入到其他用户的浏览器中。

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

目录 1. 打开浏览器开发者工具 2. 使用 Network 面板 3. 查看具体的API请求 a. Headers b. Payload c. Response d. Preview e. Timing 4. 实际操作步骤 5. 常见问题及解决方法 a. 无法看到API请求 b. 请求失败 c. 跨域问题(CORS) 作为一名后端工程师,理解前端如何调用接口、传递参数以及接收返回值是非常重要的。下面将详细介绍如何通过浏览器开发者工具(F12)查看和分析这些信息,并附带图片案例帮助你更好地理解。 1. 打开浏览器开发者工具 按下 F12 或右键点击页面选择“检查”可以打开浏览器的开发者工具。常用的浏览器如Chrome、Firefox等都内置了开发者工具。下面是我选择我的一篇文章,打开开发者工具进行演示。 2. 使用

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例)

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例) 前端开发中最令人头疼的莫过于那些难以定位的UI问题——元素错位、样式冲突、响应式失效...传统调试方式往往需要反复修改代码、刷新页面、检查元素。现在,通过Cursor编辑器集成的Codex功能,你可以直接用截图交互快速定位和修复这些问题。本文将带你从零开始,掌握这套革命性的调试工作流。 1. 环境准备与基础配置 在开始之前,确保你已经具备以下环境: * Cursor编辑器最新版(v2.5+) * Node.js 18.x及以上版本 * React 18项目(本文以Chakra UI 2.x为例) 首先在Cursor中安装Codex插件: 1. 点击左侧扩展图标 2. 搜索"Codex"并安装 3. 登录你的OpenAI账户(需要ChatGPT Plus订阅) 关键配置项: // 在项目根目录创建.