build: update agp android gradle version

update agp to 8.13.2,update gradle to 8.13,add build.gradle namespace,use android studio panda 4
This commit is contained in:
2026-06-12 18:44:30 +08:00
parent 58ddea018c
commit 5074854c40
14 changed files with 247 additions and 144 deletions

View File

@@ -3,8 +3,9 @@ apply plugin: 'com.android.library'
version = "1.3.3"
android {
namespace "com.flyco.tablayout"
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion 17

View File

@@ -1,3 +1 @@
<manifest
package="com.flyco.tablayout">
</manifest>
<manifest package="com.flyco.tablayout"></manifest>

8
MDM_Run.bat Normal file
View File

@@ -0,0 +1,8 @@
# Android Studio Panda 4 运行会报错
# Couldn't terminate previous instance of app
# 1. 构建 APK
./gradlew :app:assembleDebug
# 2. 直接安装(不主动执行 am force-stop
adb install -r -t app/build/outputs/apk/debug/app_debug.apk
# 3. 启动应用 powershell 可以用";"连接
adb shell am start -n com.xwad.os/.activity.home.HomeActivity

View File

@@ -1,7 +1,10 @@
apply plugin: 'com.android.library'
android {
namespace "com.wgw.photo.preview"
compileSdkVersion 29
defaultConfig {
minSdkVersion 23
targetSdkVersion 29

View File

@@ -1,2 +1 @@
<manifest package="com.wgw.photo.preview"
xmlns:android="http://schemas.android.com/apk/res/android"/>
<manifest package="com.wgw.photo.preview" />

View File

@@ -20,24 +20,12 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.wgw.photo.preview.PreloadImageView.DrawableLoadListener;
import com.wgw.photo.preview.interfaces.IFindThumbnailView;
import com.wgw.photo.preview.interfaces.OnDismissListener;
import com.wgw.photo.preview.util.SpannableString;
import com.wgw.photo.preview.util.Utils;
import com.wgw.photo.preview.util.notch.CutOutMode;
import com.wgw.photo.preview.util.notch.NotchAdapterUtils;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
@@ -50,6 +38,16 @@ import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle.State;
import androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener;
import com.wgw.photo.preview.PreloadImageView.DrawableLoadListener;
import com.wgw.photo.preview.interfaces.IFindThumbnailView;
import com.wgw.photo.preview.interfaces.OnDismissListener;
import com.wgw.photo.preview.util.SpannableString;
import com.wgw.photo.preview.util.Utils;
import com.wgw.photo.preview.util.notch.CutOutMode;
import com.wgw.photo.preview.util.notch.NotchAdapterUtils;
import java.util.Objects;
/**
* 预览界面根布局
*

View File

@@ -9,6 +9,9 @@ def releaseTime() {
}
android {
namespace "com.xwad.os"
buildToolsVersion "36.0.0"
compileSdkVersion 29
defaultConfig {
@@ -22,25 +25,12 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
ndk {
//根据需要 自行选择添加的对应cpu类型的.so库。
abiFilters 'armeabi-v7a', 'arm64-v8a'
// 还可以添加 'armeabi', 'x86', 'x86_64', 'mips', 'mips64'
}
dataBinding {
enabled true
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
@@ -48,6 +38,10 @@ android {
abortOnError false
}
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
@@ -66,6 +60,17 @@ android {
]
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
dataBinding true
buildConfig true
aidl true
}
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
@@ -87,70 +92,132 @@ android {
applicationVariants.all { variant ->
def variantName = variant.name.capitalize()
// 建议使用 packageApplication 任务它更明确指向 APK 生成
// 建议使用 packageApplication 任务,它更明确指向 APK 生成
def packageTask = tasks.findByName("package${variantName}")
if (packageTask) {
packageTask.doLast {
// 1. 配置路径优化:尽量使用 project 属性,避免写死 E:\ 盘符
def cerFile = file("E:\\Xuewang365\\HonorCer\\HONOR.CER")
if (!cerFile.exists()) {
println "⚠️ 未找到证书文件: ${cerFile.path}"
return
}
def sdkDir = android.sdkDirectory.path
// def buildToolsVersion = android.buildToolsVersion // 建议动态获取,除非有特定版本要求
def buildToolsVersion = "33.0.0"
def buildToolsPath = "${sdkDir}/build-tools/${buildToolsVersion}"
def aaptPath = "${buildToolsPath}/aapt${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.exe' : ''}"
def apksignerPath = "${buildToolsPath}/apksigner${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.bat' : ''}"
// 2. 关键优化:精准定位当前 Variant 的输出文件
// 使用 variant.outputs 获取当前构建生成的特定文件
variant.outputs.all { output ->
def apkFile = output.outputFile
println "APK地址:${apkFile.absolutePath}"
if (apkFile != null && apkFile.name.endsWith(".apk")) {
println "🛠️ 开始对当前 APK 注入: ${apkFile.name}"
// 3. 准备 META-INF 临时结构
def tempBaseDir = new File(project.buildDir, "intermediates/honor_cer_temp/${variant.name}")
def metaInfDir = new File(tempBaseDir, "META-INF")
metaInfDir.deleteDir() // 清理旧数据
metaInfDir.mkdirs()
def targetFile = new File(metaInfDir, cerFile.name)
ant.copy(file: cerFile, tofile: targetFile)
// 4. 调用 aapt 注入
exec {
workingDir tempBaseDir
commandLine aaptPath, "add", apkFile.absolutePath, "META-INF/${cerFile.name}"
}
// 5. 重新签名 (Apksigner)
def signingConfig = variant.signingConfig
if (signingConfig != null && signingConfig.storeFile.exists()) {
exec {
commandLine apksignerPath, "sign",
"--ks", signingConfig.storeFile.absolutePath,
"--ks-pass", "pass:${signingConfig.storePassword}",
"--ks-key-alias", signingConfig.keyAlias,
"--key-pass", "pass:${signingConfig.keyPassword}",
"--v2-signing-enabled", "true",
"--v3-signing-enabled", "true",
apkFile.path
}
println "✅ [${variant.name}] 注入并修复签名成功!"
} else {
println "❌ [${variant.name}] 签名失败SigningConfig 配置无效"
}
// 清理临时目录
tempBaseDir.deleteDir()
try {
// 1. 配置路径优化:尽量使用 project 属性,避免写死 E:\ 盘符
def cerFile = file("E:\\Huawei\\MagicOSSdk\\HONOR.CER")
if (!cerFile.exists()) {
println "⚠️ 未找到证书文件: ${cerFile.path},跳过注入步骤"
return
}
def sdkDir = android.sdkDirectory.path
// def buildToolsVersion = android.buildToolsVersion // 建议动态获取,除非有特定版本要求
def buildToolsVersion = "36.0.0"
def buildToolsPath = "${sdkDir}/build-tools/${buildToolsVersion}"
def aaptPath = "${buildToolsPath}/aapt${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.exe' : ''}"
def apksignerPath = "${buildToolsPath}/apksigner${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.bat' : ''}"
// 验证工具是否存在
if (!file(aaptPath).exists()) {
println "❌ 未找到 aapt 工具: ${aaptPath}"
return
}
if (!file(apksignerPath).exists()) {
println "❌ 未找到 apksigner 工具: ${apksignerPath}"
return
}
// 2. 关键优化:精准定位当前 Variant 的输出文件
// 使用 variant.outputs 获取当前构建生成的特定文件
variant.outputs.each { output ->
def apkFile = output.outputFile
if (apkFile == null) {
println "⚠️ APK 文件为 null,跳过处理"
return
}
if (!apkFile.exists()) {
println "⚠️ APK 文件不存在: ${apkFile.absolutePath},跳过处理"
return
}
println "APK地址:${apkFile.absolutePath}"
if (apkFile.name.endsWith(".apk")) {
println "🛠️ 开始对当前 APK 注入: ${apkFile.name}"
try {
// 3. 准备 META-INF 临时结构
def tempBaseDir = new File(project.buildDir, "intermediates/honor_cer_temp/${variant.name}")
def metaInfDir = new File(tempBaseDir, "META-INF")
// 确保清理旧数据
if (metaInfDir.exists()) {
metaInfDir.deleteDir()
}
metaInfDir.mkdirs()
def targetFile = new File(metaInfDir, cerFile.name)
ant.copy(file: cerFile, tofile: targetFile)
// 4. 调用 aapt 注入 - 添加错误输出捕获
println "执行命令: ${aaptPath} add ${apkFile.absolutePath} META-INF/${cerFile.name}"
def aaptResult = exec {
workingDir tempBaseDir
commandLine aaptPath, "add", apkFile.absolutePath, "META-INF/${cerFile.name}"
ignoreExitValue = true // 不立即失败,让我们自己处理
standardOutput = new ByteArrayOutputStream()
errorOutput = new ByteArrayOutputStream()
}
if (aaptResult.exitValue != 0) {
def errorMsg = aaptResult.errorOutput.toString()
println "❌ aapt 执行失败 (退出码: ${aaptResult.exitValue})"
println "错误信息: ${errorMsg}"
println "尝试继续重新签名..."
} else {
println "✅ aapt 注入成功"
}
// 5. 重新签名 (Apksigner)
def signingConfig = variant.signingConfig
if (signingConfig != null && signingConfig.storeFile != null && signingConfig.storeFile.exists()) {
println "执行签名..."
def signResult = exec {
commandLine apksignerPath, "sign",
"--ks", signingConfig.storeFile.absolutePath,
"--ks-pass", "pass:${signingConfig.storePassword}",
"--ks-key-alias", signingConfig.keyAlias,
"--key-pass", "pass:${signingConfig.keyPassword}",
"--v2-signing-enabled", "true",
"--v3-signing-enabled", "true",
apkFile.path
ignoreExitValue = true
standardOutput = new ByteArrayOutputStream()
errorOutput = new ByteArrayOutputStream()
}
if (signResult.exitValue == 0) {
println "✅ [${variant.name}] 注入并修复签名成功!"
} else {
def errorMsg = signResult.errorOutput.toString()
println "❌ [${variant.name}] 签名失败 (退出码: ${signResult.exitValue})"
println "错误信息: ${errorMsg}"
}
} else {
println "❌ [${variant.name}] 签名失败:SigningConfig 配置无效"
}
// 清理临时目录
if (tempBaseDir.exists()) {
tempBaseDir.deleteDir()
}
} catch (Exception e) {
println "❌ 处理 APK 时发生异常: ${e.message}"
e.printStackTrace()
}
}
}
} catch (Exception e) {
println "❌ 证书注入过程发生严重错误: ${e.message}"
e.printStackTrace()
// 不中断构建流程
}
}
}
@@ -161,44 +228,34 @@ android {
debug {
versionNameSuffix "-debug"
minifyEnabled false
//Zipalign优化
zipAlignEnabled true
buildConfigField "String", "platform", '"HONOR"'
signingConfig signingConfigs.tuixin
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (outputFile != null) {
// def app_name = getResValues().get("app_name").value
def fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType.name}.apk"
output.outputFileName = fileName
}
}
}
}
release {
minifyEnabled false
//Zipalign优化
zipAlignEnabled true
//前一部分代表系统默认的android程序的混淆文件该文件已经包含了基本的混淆声明后一个文件是自己的定义混淆文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//签名
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.tuixin
buildConfigField "String", "platform", '"HONOR"'
// 将release版本的包名重命名加上版本及日期
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = ""
if (outputFile != null) {
// def app_name = getResValues().get("app_name").value
def fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType.name}.apk"
output.outputFileName = new File(outputFile, fileName)
}
}
}
}
}
// Add application variant configuration here instead
applicationVariants.all { variant ->
variant.outputs.each { output ->
def buildType = variant.buildType.name
def fileName = ""
if (buildType.contains("debug")) {
fileName = "${appName()}_V${defaultConfig.versionName}_${releaseTime()}.apk"
} else {
fileName = "${appName()}_${variant.versionCode}_V${variant.versionName}_${releaseTime()}_${buildType}.apk"
}
output.outputFileName = fileName
}
}
}
@@ -316,22 +373,32 @@ dependencies {
implementation 'org.greenrobot:eventbus:3.3.1'
}
preBuild {
doLast {
def imlFile = file(project.name + ".iml")
// def imlFile = file("..\\.idea\\modules\\" + project.name + "\\" + rootProject.name + "." + project.name + ".iml")
println 'Change ' + project.name + '.iml order'
try {
def parsedXml = (new XmlParser()).parse(imlFile)
def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
println 'what' + sdkString
new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
// nop, iml not found
println "no iml found"
}
// 在 dependencies 之后添加
project.afterEvaluate {
android.applicationVariants.all { variant ->
variant.javaCompileProvider.get().options.bootstrapClasspath = files(
file('libs/framework.jar'),
android.getBootClasspath()
)
}
}
//preBuild {
// doLast {
// def imlFile = file(project.name + ".iml")
//// def imlFile = file("..\\.idea\\modules\\" + project.name + "\\" + rootProject.name + "." + project.name + ".iml")
// println 'Change ' + project.name + '.iml order'
// try {
// def parsedXml = (new XmlParser()).parse(imlFile)
// def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
// parsedXml.component[1].remove(jdkNode)
// def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
// println 'what' + sdkString
// new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
// groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
// } catch (FileNotFoundException e) {
// // nop, iml not found
// println "no iml found"
// }
// }
//}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#EEEEEE" />
<corners android:radius="4dp" />
</shape>

View File

@@ -3,10 +3,11 @@
buildscript {
repositories {
google()
// mavenCentral()
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url 'https://developer.hihonor.com/repo' }
maven { url 'https://maven.google.com' }
maven { url 'https://developer.huawei.com/repo/' }
maven { url 'https://developer.hihonor.com/repo' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/public' }
@@ -14,7 +15,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath 'com.android.tools.build:gradle:8.13.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -25,12 +26,35 @@ allprojects {
configurations.all {
resolutionStrategy {
force 'androidx.constraintlayout:constraintlayout:2.0.4'
force 'androidx.core:core:1.5.0'
//for targetSdkVersion 29
force 'androidx.activity:activity:1.2.2'
force 'androidx.lifecycle:lifecycle-livedata:2.3.1'
force 'androidx.lifecycle:lifecycle-livedata-core:2.3.1'
force 'androidx.lifecycle:lifecycle-runtime:2.3.1'
force 'androidx.lifecycle:lifecycle-viewmodel:2.3.1'
force 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1'
force 'androidx.lifecycle:lifecycle-service:2.3.1'
force 'androidx.lifecycle:lifecycle-process:2.3.1'
force 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
force 'androidx.savedstate:savedstate:1.1.0'
force 'androidx.profileinstaller:profileinstaller:1.1.0'
force 'androidx.startup:startup-runtime:1.0.0'
force 'androidx.arch.core:core-runtime:2.1.0'
force 'androidx.sqlite:sqlite:2.1.0'
force 'androidx.sqlite:sqlite-framework:2.1.0'
force 'androidx.fragment:fragment:1.3.6'
force 'androidx.room:room-runtime:2.3.0'
}
}
repositories {
google()
// mavenCentral()
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url 'https://maven.google.com' }
maven { url 'https://developer.huawei.com/repo/' }
maven { url 'https://developer.hihonor.com/repo' }
maven { url 'https://maven.aliyun.com/repository/central' }

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip

View File

@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'
android {
namespace "com.shehuan.niv"
compileSdkVersion 28
defaultConfig {

View File

@@ -1,2 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shehuan.niv" />
<manifest package="com.shehuan.niv" />

View File

@@ -1,9 +1,9 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
namespace "com.tuo.customview"
compileSdkVersion 25
defaultConfig {
minSdkVersion 15

View File

@@ -1,2 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tuo.customview" />
<manifest package="com.tuo.customview" />