@@ -18,6 +18,8 @@ import java.io.File
1818import java.io.FileOutputStream
1919import java.io.PrintWriter
2020import java.io.StringWriter
21+ import java.nio.file.Files
22+ import java.nio.file.StandardCopyOption
2123import java.util.logging.Logger
2224import java.util.zip.ZipEntry
2325import java.util.zip.ZipFile
@@ -178,6 +180,12 @@ internal object PatchCommand : Runnable {
178180
179181 private var aaptBinaryPath: File ? = null
180182
183+ @CommandLine.Option (
184+ names = [" --custom-zipalign-binary" ],
185+ description = [" Path to a custom zipalign binary." ],
186+ )
187+ private var zipalignBinaryPath: File ? = null
188+
181189 @CommandLine.Option (
182190 names = [" --purge" ],
183191 description = [" Purge temporary files directory after patching." ],
@@ -356,27 +364,26 @@ internal object PatchCommand : Runnable {
356364
357365 // zipalign logic start
358366 if (! mount) {
359- try {
360- logger.info(" Running zipalign..." )
361- val alignedApk = File .createTempFile(" aligned" , " .apk" , temporaryFilesPath)
362- val pb = ProcessBuilder (
363- " zipalign" , " -p" , " -f" , " 4" ,
364- patchedApkFile.absolutePath,
365- alignedApk.absolutePath
366- )
367- val process = pb.start()
368- if (process.waitFor() == 0 ) {
369- if (patchedApkFile.delete()) {
370- alignedApk.renameTo(patchedApkFile)
371- logger.info(" zipalign completed" )
372- }
373- } else {
374- logger.warning(" zipalign failed (exit code ${process.exitValue()} )" )
375- alignedApk.delete()
376- }
377- } catch (e: Exception ) {
378- logger.warning(" Failed to run zipalign: ${e.message} . Ensure it is in PATH." )
367+ logger.info(" Running zipalign" )
368+ val alignedApk = File .createTempFile(" aligned" , " .apk" , temporaryFilesPath)
369+ val zipalign = zipalignBinaryPath?.absolutePath ? : " zipalign"
370+
371+ val process = ProcessBuilder (
372+ zipalign, " -p" , " -f" , " 4" ,
373+ patchedApkFile.absolutePath,
374+ alignedApk.absolutePath
375+ ).redirectErrorStream(true ).start()
376+
377+ // Consume output to prevent buffer blocking and for debug logging
378+ val output = process.inputStream.bufferedReader().use { it.readText() }
379+ val exitCode = process.waitFor()
380+
381+ if (exitCode != 0 ) {
382+ throw RuntimeException (" zipalign failed (exit code $exitCode ):\n $output " )
379383 }
384+
385+ Files .move(alignedApk.toPath(), patchedApkFile.toPath(), StandardCopyOption .REPLACE_EXISTING )
386+ logger.info(" zipalign completed" )
380387 }
381388 // zipalign logic end
382389
0 commit comments