From 8519e816a3f6ba833580b6138148d8d38820d3a1 Mon Sep 17 00:00:00 2001 From: Lin <106499400+LYS86@users.noreply.github.com> Date: Thu, 25 Dec 2025 15:06:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/autojs/autojs/ui/error/ErrorDialogActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java b/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java index 13a68b5b7..14f9f3b80 100644 --- a/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java +++ b/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java @@ -20,8 +20,8 @@ public class ErrorDialogActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); + super.onCreate(savedInstanceState); // Get extras from intent Intent intent = getIntent(); From d992e3fa2b95851c51a26d22321de814ff5901ca Mon Sep 17 00:00:00 2001 From: Lin <106499400+LYS86@users.noreply.github.com> Date: Thu, 25 Dec 2025 18:07:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=E4=BD=BF=E7=94=A8D8=E5=A4=84=E7=90=86j?= =?UTF-8?q?ar=EF=BC=8C=E8=A7=A3=E5=86=B3=E9=83=A8=E5=88=86jar=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=8A=A0=E8=BD=BD=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 + .../autojs/autojs/rhino/AndroidClassLoader.kt | 49 ++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4f04e01f3..6b77a97cb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -241,6 +241,8 @@ dependencies /* Unclassified */ { // ICU4J implementation("com.ibm.icu:icu4j:77.1") + + implementation("com.android.tools:r8:8.13.17") } dependencies /* MIME */ { diff --git a/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt b/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt index b9e2c95d5..7926f4d0c 100644 --- a/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt +++ b/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt @@ -3,6 +3,10 @@ package org.autojs.autojs.rhino import android.os.Build import android.util.Log import com.android.dx.command.dexer.Main +import com.android.tools.r8.CompilationMode +import com.android.tools.r8.D8 +import com.android.tools.r8.D8Command +import com.android.tools.r8.OutputMode import dalvik.system.DexClassLoader import net.lingala.zip4j.ZipFile import net.lingala.zip4j.exception.ZipException @@ -84,8 +88,18 @@ class AndroidClassLoader(private val parent: ClassLoader, private val cacheDir: } } - @Throws(IOException::class) fun loadJar(file: File): DexClassLoader { + try { + val dexFile = jarToDex(file, cacheDir) + return loadDex(dexFile) + } catch (e: Exception) { + Log.e(TAG, "loadJar: failed to load jar ${file.path}", e) + return loadJar1(file) + } + } + + @Throws(IOException::class) + fun loadJar1(file: File): DexClassLoader { val path = file.path Log.d(TAG, "loadJar: jar = $path") if (!file.exists() || !file.canRead()) { @@ -215,6 +229,39 @@ class AndroidClassLoader(private val parent: ClassLoader, private val cacheDir: private fun generateDexFileName(jar: File) = md5("${jar.path}_${jar.lastModified()}") + private fun jarToDex(jar: File, cacheDir: File): File { + val dexName = generateDexFileName(jar) + val dexFile = File(cacheDir, "$dexName.dex") + if (dexFile.exists()) { + return dexFile + } + val tmpOut = File(cacheDir, "${dexName}_tmp").apply { mkdirs() } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val cmd = D8Command.builder() + .addProgramFiles(jar.toPath()) + .setOutput(tmpOut.toPath(), OutputMode.DexIndexed) + .setMode(CompilationMode.RELEASE) + .build() + D8.run(cmd) + } else { + val args = arrayOf( + "--output", tmpOut.absolutePath, + "--release", + jar.absolutePath + ) + D8.main(args) + } + val classesDex = File(tmpOut, "classes.dex") + if (classesDex.exists().not()) { + throw IOException("R8 did not produce classes.dex") + } + if (classesDex.renameTo(dexFile).not()) { + dexFile.outputStream().use { out -> classesDex.inputStream().use { it.copyTo(out) } } + } + tmpOut.deleteRecursively() + return dexFile + } + companion object { private val TAG = AndroidClassLoader::class.java.simpleName