diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e7d4b2..dc19c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## [4.0.2-dev.2](https://github.com/ReVanced/revanced-library/compare/v4.0.2-dev.1...v4.0.2-dev.2) (2026-04-09) + + +### Performance Improvements + +* Build patched DEX files and resources before opening APK for writing to reduce memory usage on one spot ([369eb03](https://github.com/ReVanced/revanced-library/commit/369eb0392f539187dce0b0c246d5ca72e0d80c99)) + +## [4.0.2-dev.1](https://github.com/ReVanced/revanced-library/compare/v4.0.1...v4.0.2-dev.1) (2026-04-04) + + +### Bug Fixes + +* Ensure stdout/stderr is captured to avoid empty command output ([#117](https://github.com/ReVanced/revanced-library/issues/117)) ([429a5f0](https://github.com/ReVanced/revanced-library/commit/429a5f0adb50d88ddcc450e5e22e25063ddad067)) + ## [4.0.1](https://github.com/ReVanced/revanced-library/compare/v4.0.0...v4.0.1) (2026-02-25) diff --git a/gradle.properties b/gradle.properties index 29c863f..27f5f05 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 4.0.1 +version = 4.0.2-dev.2 #Gradle org.gradle.jvmargs = -Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options="-Xmx2048M" org.gradle.caching = true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7ec6401..95517e3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ jadb = "1.2.1.1" kotlin = "2.3.10" kotlinx-coroutines = "1.10.2" kotlinx-serialization = "1.10.0" -libsu = "5.2.2" +libsu = "6.0.0" revanced-patcher = "22.0.0" bouncy-castle = "1.83" sigstore = "2.0.0" diff --git a/library/src/androidMain/kotlin/app/revanced/library/installation/command/LocalShellCommandRunner.kt b/library/src/androidMain/kotlin/app/revanced/library/installation/command/LocalShellCommandRunner.kt index 4ddd54a..346a4d6 100644 --- a/library/src/androidMain/kotlin/app/revanced/library/installation/command/LocalShellCommandRunner.kt +++ b/library/src/androidMain/kotlin/app/revanced/library/installation/command/LocalShellCommandRunner.kt @@ -34,11 +34,19 @@ class LocalShellCommandRunner internal constructor( RootService.bind(intent, this) } - override fun runCommand(command: String) = shell.newJob().add(command).exec().let { - object : RunResult { - override val exitCode = it.code - override val output by lazy { it.out.joinToString("\n") } - override val error by lazy { it.err.joinToString("\n") } + override fun runCommand(command: String): RunResult { + val stdout = mutableListOf() + val stderr = mutableListOf() + val result = shell.newJob().add(command).to(stdout, stderr).exec() + + return object : RunResult { + override val exitCode = result.code + override val output: String by lazy { + stdout.joinToString("\n") + } + override val error: String by lazy { + stderr.joinToString("\n") + } } } diff --git a/library/src/commonMain/kotlin/app/revanced/library/ApkUtils.kt b/library/src/commonMain/kotlin/app/revanced/library/ApkUtils.kt index bea9f0f..1bec89e 100644 --- a/library/src/commonMain/kotlin/app/revanced/library/ApkUtils.kt +++ b/library/src/commonMain/kotlin/app/revanced/library/ApkUtils.kt @@ -51,6 +51,10 @@ object ApkUtils { * @param apkFile The file to apply the patched files to. */ fun PatchesResult.applyTo(apkFile: File) { + // Resolve before opening the APK file, since these are lazy properties and require some memory. + val dexFiles = dexFiles + val resources = resources + ZFile.openReadWrite(apkFile, zFileOptions).use { targetApkZFile -> dexFiles.forEach { dexFile -> targetApkZFile.add(dexFile.name, dexFile.stream) diff --git a/library/src/commonMain/kotlin/app/revanced/library/installation/installer/RootInstaller.kt b/library/src/commonMain/kotlin/app/revanced/library/installation/installer/RootInstaller.kt index b53d9cc..27992f6 100644 --- a/library/src/commonMain/kotlin/app/revanced/library/installation/installer/RootInstaller.kt +++ b/library/src/commonMain/kotlin/app/revanced/library/installation/installer/RootInstaller.kt @@ -100,7 +100,7 @@ abstract class RootInstaller internal constructor( /** * Runs a command on the device. */ - protected operator fun String.invoke() = shellCommandRunner("su -c \'$this\'") + protected operator fun String.invoke() = shellCommandRunner(this) /** * Moves the given file to the given [targetFilePath]. @@ -127,7 +127,7 @@ abstract class RootInstaller internal constructor( } } - internal class FailedToFindInstalledPackageException internal constructor(packageName: String) : Exception("Failed to find installed package \"$packageName\" because no activity was found") + internal class FailedToFindInstalledPackageException internal constructor(packageName: String) : Exception("Failed to resolve installed APK path for package \"$packageName\"") internal class PackageNameRequiredException internal constructor() : Exception("Package name is required") internal class NoRootPermissionException internal constructor() : Exception("No root permission")