Incorpora i simboli nativi nell’AAB per Play Console.

Le .so AndroidX sono già stripped: AGP non generava metadata; ora le iniettiamo nel bundle prima della firma (release 2.0.9 / 30).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 19:36:39 +02:00
co-authored by Cursor
parent d85bab30d1
commit 5daada81b0
+90 -3
View File
@@ -1,4 +1,7 @@
import java.util.Properties import java.util.Properties
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
plugins { plugins {
id("com.android.application") id("com.android.application")
@@ -20,13 +23,18 @@ android {
applicationId = "com.matchlivetv.match_live_tv" applicationId = "com.matchlivetv.match_live_tv"
minSdk = 24 minSdk = 24
targetSdk = 36 targetSdk = 36
versionCode = 29 versionCode = 30
versionName = "2.0.8-native" versionName = "2.0.9-native"
val apiBaseUrl = project.findProperty("API_BASE_URL") as String? val apiBaseUrl = project.findProperty("API_BASE_URL") as String?
?: "https://www.matchlivetv.it" ?: "https://www.matchlivetv.it"
buildConfigField("String", "API_BASE_URL", "\"$apiBaseUrl\"") buildConfigField("String", "API_BASE_URL", "\"$apiBaseUrl\"")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// Anche in defaultConfig: AGP estrae simboli se le .so non sono già stripped.
ndk {
debugSymbolLevel = "SYMBOL_TABLE"
}
} }
signingConfigs { signingConfigs {
@@ -47,7 +55,8 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro", "proguard-rules.pro",
) )
// Simboli .so per crash/ANR su Play Console (evita l'avviso "native code senza debug symbols") // Le .so AndroidX arrivano già stripped: AGP non genera metadata.
// Il task injectNativeDebugSymbolsInReleaseBundle le incorpora nell'AAB.
ndk { ndk {
debugSymbolLevel = "SYMBOL_TABLE" debugSymbolLevel = "SYMBOL_TABLE"
} }
@@ -112,3 +121,81 @@ dependencies {
androidTestImplementation("androidx.test:core:1.6.1") androidTestImplementation("androidx.test:core:1.6.1")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0") androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
} }
// Play Console: le .so prebuilt (AndroidX) sono già stripped → AGP non aggiunge
// BUNDLE-METADATA/com.android.tools.build.debugsymbols. Incorporiamo un zip ABI/.so
// nell'intermediary bundle prima della firma.
val injectNativeDebugSymbolsInReleaseBundle by tasks.registering {
description = "Embed native-debug-symbols.zip into the release AAB intermediary"
val mergeNative = tasks.named("mergeReleaseNativeLibs")
val packageBundle = tasks.named("packageReleaseBundle")
dependsOn(mergeNative, packageBundle)
inputs.dir(
layout.buildDirectory.dir(
"intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib",
),
)
inputs.file(
layout.buildDirectory.file(
"intermediates/intermediary_bundle/release/packageReleaseBundle/intermediary-bundle.aab",
),
)
outputs.file(
layout.buildDirectory.file(
"intermediates/intermediary_bundle/release/packageReleaseBundle/intermediary-bundle.aab",
),
)
doLast {
val libsDir = layout.buildDirectory
.dir("intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib")
.get()
.asFile
val aabFile = layout.buildDirectory
.file("intermediates/intermediary_bundle/release/packageReleaseBundle/intermediary-bundle.aab")
.get()
.asFile
require(libsDir.isDirectory) { "Native libs missing: $libsDir" }
require(aabFile.isFile) { "Intermediary AAB missing: $aabFile" }
val workDir = layout.buildDirectory.dir("tmp/native-debug-symbols-inject").get().asFile
workDir.deleteRecursively()
workDir.mkdirs()
val symbolsZip = workDir.resolve("native-debug-symbols.zip")
ZipOutputStream(symbolsZip.outputStream().buffered()).use { zos ->
libsDir.walkTopDown().filter { it.isFile && it.extension == "so" }.forEach { so ->
val rel = so.relativeTo(libsDir).invariantSeparatorsPath
zos.putNextEntry(ZipEntry(rel))
so.inputStream().use { it.copyTo(zos) }
zos.closeEntry()
}
}
val metaPath = "BUNDLE-METADATA/com.android.tools.build.debugsymbols/native-debug-symbols.zip"
val outAab = workDir.resolve("intermediary-with-symbols.aab")
ZipFile(aabFile).use { src ->
ZipOutputStream(outAab.outputStream().buffered()).use { dst ->
val entries = src.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
if (entry.name == metaPath) continue
val newEntry = ZipEntry(entry.name)
newEntry.time = entry.time
// Deflate all entries when rewriting; STORED copy is fragile across ZipFile.
newEntry.method = ZipEntry.DEFLATED
dst.putNextEntry(newEntry)
src.getInputStream(entry).use { it.copyTo(dst) }
dst.closeEntry()
}
dst.putNextEntry(ZipEntry(metaPath))
symbolsZip.inputStream().use { it.copyTo(dst) }
dst.closeEntry()
}
}
outAab.copyTo(aabFile, overwrite = true)
logger.lifecycle("Injected $metaPath (${symbolsZip.length()} bytes) into ${aabFile.name}")
}
}
tasks.matching { it.name == "signReleaseBundle" }.configureEach {
dependsOn(injectNativeDebugSymbolsInReleaseBundle)
}