打算升级公司app安卓端的api版本,从28升级到33,主要是分几部分吧,安卓sdk升级、gradle升级、jdk和kotlin升级、第三方sdk升级。
一、升级后安卓各sdk版本
compileSdk 33
buildToolsVersion "33.0.2"
targetSdk 33
minSdk 21
二、问题记录
系统通知:api31的新特性。PendingIntent类型在api31及以上版本,只能指定FLAG_IMMUTABLE或者FLAG_MUTABLE,我个人理解是说明自己app发送的通知是否可以进行交互,比如在通知栏回复消息等,FLAG_IMMUTABLE就是普通通知不能交互,FLAG_MUTABLE是可变通知,可以自定义一些交互操作。
//通知适配api 31
int intentFlag = PendingIntent.FLAG_UPDATE_CURRENT;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
intentFlag = PendingIntent.FLAG_IMMUTABLE;
}
activity增加export属性:考虑过用脚本自动添加,但是兼容性不太好,还是自己手动一个一个添加上吧,如果是第三方的sdk,就升级版本或者更换sdk。
kotlinx.android.synthetic:删除。因被官方废弃,已无法使用,用dataBinding替换
Loombok:删除。无法正常生成class,更换最新版本也不行,最终决定删除此插件。个人觉得这个插件太鸡肋,没啥用处。
Room:使用方式改为kotlin。之前使用java写的,但是注解生成的class中个别函数会报权限不够,使用kotlin实现后问题消失。
arouter-api:升级到1.5.2,对应的arouter-compiler也升级到1.5.2。配置方式也要改,之前使用annotationProcessorOptions的方式,会导致使用Uri作为路径的的跳转报错There's no route matched!Path = xxxx。
apply plugin: 'kotlin-kapt'
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
可空类型:很多地方不能使用可空类型,例如"xxx?.xxx",要改成非空类型的。目前发现的地方不多,比如使用arouter时给参数的注解@Autowired,不能使用下面的方式
@JvmField
@Autowired
var isRoom: Boolean? = null
要改成
@JvmField
@Autowired
var isRoom: Boolean = false
glide: compiler增加kapt的配置。其他三分sdk也类似,java、kotlin混合开发的项目尽量用kapt替换java的注解方式annotationProcessor,不然有些地方的注解无法生效,kapt可以兼容annotationProcessor。
三、更新后各gradle文件内容
setting.gradle
pluginManagement {
repositories {
maven { url "https://maven.rongcloud.cn/repository/maven-releases/" }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
maven { url "https://mvn.mob.com/android" }
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://artifact.bytedance.com/repository/Volcengine/' }
maven { url 'https://jitpack.io' }
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
/**
* 存储库模式:
* PREFER_PROJECT --首选项目远程仓库
* PREFER_SETTINGS--首选settings远程仓库
* FAIL_ON_PROJECT_REPOS--强制settings远程仓库
*/
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)//设置存储库的方法
repositories {
maven { url "https://maven.rongcloud.cn/repository/maven-releases/" }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
maven { url "https://mvn.mob.com/android" }
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://artifact.bytedance.com/repository/Volcengine/' }
maven { url 'https://jitpack.io' }
gradlePluginPortal()
google()
mavenCentral()
}
}
rootProject.name = "xxxx"
include ':app'
include ':lib_net'
include ':module_xxx'
include ':module_xxx'
项目根目录build.gradle
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
主项目(app)目录build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'com.bytedance.std.tracker'
}
apply from: 'reinforce.gradle'
static def releaseTime() {
return new Date().format("yyyy-MM-dd-HH-mm", TimeZone.getTimeZone("UTC"))
}
def fileArray = []
def getBuildTime() {
return new Date().format("yyyy-MM-dd-HH-mm")
}
android {
compileSdk build_versions.compile_sdk
defaultConfig {
applicationId active.applicationId
minSdk build_versions.min_sdk
targetSdk build_versions.target_sdk
versionCode build_versions.version_code
versionName build_versions.version_name
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
kapt {
arguments {
arg("AROUTER_MODULE_NAME",project.getName() )
}
}
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'arm64-v8a'
}
vectorDrawables {
useSupportLibrary true
}
configurations.all {
resolutionStrategy { force 'androidx.core:core-ktx:1.6.0' }
}
}
getFlavorDimensionList().add("version")
buildFeatures{
dataBinding true
viewBinding true
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
signingConfigs {
debug {
storeFile file("xxx.jks")
storePassword "xxxx"
keyAlias "xxx"
keyPassword "xxx"
}
release {
storeFile file("xxx.jks")
storePassword "xxxx"
keyAlias "xxx"
keyPassword "xxx"
}
}
buildTypes {
release {
// // zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。
// zipAlignEnabled false
// // 压缩资源
// shrinkResources false
minifyEnabled false //是否启动混淆 ture:打开 false:关闭
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
applicationVariants.all { variant ->
if (variant.buildType.name == 'release') { //如果是release版本
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) { //查找所有的apk
def fileName = "${active.apkName}-${variant.productFlavors[0].name}_${versionName}_${versionCode}_${releaseTime()}.apk"
//重新定义apk的名称
output.outputFileName = fileName //outputFile.parent参数可以改成你你想要的发布路径
println(outputFile.parentFile.absolutePath + File.separator + fileName)
fileArray.add(outputFile.parentFile.absolutePath + File.separator + fileName)
}
}
}
}
}
debug {
// zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。
// zipAlignEnabled false
// 压缩资源
// shrinkResources false
// 开启混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
applicationVariants.all { variant ->
if (variant.buildType.name == 'debug') {
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) { //查找所有的apk
def fileName = "${active.apkName}-${variant.buildType.name}-${variant.productFlavors[0].name}-${getBuildTime()}.apk"
output.outputFileName = fileName //outputFile.parent参数可以改成你你想要的发布路径
fileArray.add(outputFile.parentFile.absolutePath + File.separator + fileName)
}
}
}
}
}
}
//多渠道打包
productFlavors {
//默认打包渠道
channel_app {
manifestPlaceholders = [CHANNEL_ID: active.channelId]
}
//其他打包渠道
file("./channel_list.txt").eachLine { line ->
def words = line.split(":")
def key = words[0]
def channel = words[1]
def name = channel
"$name" {
manifestPlaceholders = [(key): "$channel"]
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
implementation deps.androidx.constraintlayout
implementation deps.androidx.appcompat
implementation project(path: ':lib_common')
implementation project(path: ':module_xxx')
implementation project(path: ':module_xxx')
implementation project(path: ':module_xxx')
}
各module通用build.gradle
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
android {
compileSdk build_versions.compile_sdk
buildToolsVersion build_versions.build_tools
defaultConfig {
minSdk build_versions.min_sdk
targetSdk build_versions.target_sdk
versionCode build_versions.version_code
versionName build_versions.version_name
consumerProguardFiles 'consumer-rules.pro'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
//jni库统一放在libs目录下
// jniLibs.srcDir = ['libs']
if (isBuildModule.toBoolean()) {
//单独运行
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
//合并到宿主中
manifest.srcFile 'src/main/AndroidManifest.xml'
resources {
//正式版本时.剔除debug文件夹下的所有调式文件
exclude 'src/debug/*'
}
}
}
}
buildFeatures {
dataBinding true
viewBinding true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
}
四、参考资料:
zhuanlan.zhihu.com/p/556817634…