6.6.2 - Alpha - 修复 plugins.load; 优化 dex 文件加载方式 (issue #290)

This commit is contained in:
SuperMonster003
2025-01-13 01:30:56 +08:00
parent f68880f3b6
commit 49fac78fec
5 changed files with 51 additions and 15 deletions

View File

@@ -3,9 +3,11 @@
"v6.6.2": { "v6.6.2": {
"released_date": "2025/01/03", "released_date": "2025/01/03",
"fix": [ "fix": [
"notice 模块缺失 getBuilder 等扩展方法的问题 _[`issue #301`](http://issues.autojs6.com/301)_", "plugins.load 方法无法正常加载插件的问题 _[`issue #290`](http://issues.autojs6.com/290)_",
"dex 文件可能因权限问题无法正常加载的问题 (试修) _[`issue #290`](http://issues.autojs6.com/290)_",
"dx 库在 Android 7.x 无法正常使用的问题 _[`issue #293`](http://issues.autojs6.com/293)_", "dx 库在 Android 7.x 无法正常使用的问题 _[`issue #293`](http://issues.autojs6.com/293)_",
"ScriptRuntime 使用 require 引用内置模块时可能出现的同步状态异常 (试修)_[`issue #298`](http://issues.autojs6.com/298)_", "ScriptRuntime 使用 require 引用内置模块时可能出现的同步状态异常 (试修)_[`issue #298`](http://issues.autojs6.com/298)_",
"notice 模块缺失 getBuilder 等扩展方法的问题 _[`issue #301`](http://issues.autojs6.com/301)_",
"floaty.window/floaty.rawWindow 无法在子线程执行的问题" "floaty.window/floaty.rawWindow 无法在子线程执行的问题"
], ],
"improvement": [ "improvement": [

View File

@@ -3,7 +3,6 @@ package org.autojs.autojs.rhino
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import com.android.dx.command.dexer.Main import com.android.dx.command.dexer.Main
import com.legacy.android.dx.command.dexer.Main as LegacyMain
import dalvik.system.DexClassLoader import dalvik.system.DexClassLoader
import net.lingala.zip4j.ZipFile import net.lingala.zip4j.ZipFile
import net.lingala.zip4j.exception.ZipException import net.lingala.zip4j.exception.ZipException
@@ -17,6 +16,7 @@ import java.io.ByteArrayInputStream
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import com.legacy.android.dx.command.dexer.Main as LegacyMain
/** /**
* Created by Stardust on Apr 5, 2017. * Created by Stardust on Apr 5, 2017.
@@ -50,22 +50,37 @@ class AndroidClassLoader(private val parent: ClassLoader, private val cacheDir:
@Throws(FileNotFoundException::class) @Throws(FileNotFoundException::class)
fun loadDex(file: File): DexClassLoader { fun loadDex(file: File): DexClassLoader {
val path = file.path val originalPath = file.path
Log.d(TAG, "loadDex: file = $path") Log.d(TAG, "loadDex: file = $originalPath")
if (!file.exists() || !file.canRead()) { if (!file.exists() || !file.canRead()) {
throw FileNotFoundException(str(R.string.file_not_exist_or_readable, path)) throw FileNotFoundException(str(R.string.file_not_exist_or_readable, originalPath))
} }
// @Hint by SuperMonster003 on Nov 30, 2023. // @Hint by SuperMonster003 on Nov 30, 2023.
// ! Try to avoid the exception which looks like below (API Level 34+): // ! Try to avoid the exception which looks like below (API Level 34+):
// # java.lang.SecurityException: Writable dex file '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar' is not allowed. // # java.lang.SecurityException: Writable dex file '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar' is not allowed.
// ! zh-CN: // ! zh-CN: 尝试避免如下异常 (API 级别 34+):
// ! 尝试避免如下异常 (API 级别 34+):
// # java.lang.SecurityException: 不允许可写的 dex 文件 '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar'. // # java.lang.SecurityException: 不允许可写的 dex 文件 '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar'.
file.setReadOnly() // !
// @Hint by SuperMonster003 on Jan 13, 2025.
// ! Copy the dex file to the cache path and set it as read-only.
// ! zh-CN: 将 dex 文件复制到缓存路径并设置只读.
// # file.setReadOnly()
val safeDexFile = File(cacheDir, "safe_${file.name}")
try {
if (!safeDexFile.exists() || md5(file) != md5(safeDexFile)) {
file.copyTo(safeDexFile, overwrite = true)
}
if (!safeDexFile.setReadOnly()) {
Log.e(TAG, "Failed to set file as read-only: ${safeDexFile.path}")
}
} catch (e: IOException) {
throw FatalLoadingException(e)
}
return DexClassLoader(path, cacheDir.path, null, parent).also { return DexClassLoader(safeDexFile.path, cacheDir.path, null, parent).also {
mDexClassLoaders[path] = it mDexClassLoaders[safeDexFile.path] = it
} }
} }

View File

@@ -4,6 +4,7 @@ import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
import org.autojs.autojs.extension.FlexibleArray import org.autojs.autojs.extension.FlexibleArray
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.augment.Augmentable import org.autojs.autojs.runtime.api.augment.Augmentable
import org.autojs.autojs.runtime.api.augment.Invokable
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.RhinoUtils.callFunction import org.autojs.autojs.util.RhinoUtils.callFunction
import org.autojs.autojs.util.RhinoUtils.coerceString import org.autojs.autojs.util.RhinoUtils.coerceString
@@ -12,18 +13,21 @@ import org.mozilla.javascript.BaseFunction
import kotlin.text.RegexOption.IGNORE_CASE import kotlin.text.RegexOption.IGNORE_CASE
@Suppress("unused", "UNUSED_PARAMETER") @Suppress("unused", "UNUSED_PARAMETER")
class Plugins(scriptRuntime: ScriptRuntime) : Augmentable() { class Plugins(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
override val selfAssignmentFunctions = listOf( override val selfAssignmentFunctions = listOf(
::load.name, ::load.name,
) )
override fun invoke(vararg args: Any?): Any? = ensureArgumentsOnlyOne(args) { o ->
load(scriptRuntime, arrayOf(o))
}
companion object : FlexibleArray() { companion object : FlexibleArray() {
@JvmStatic @JvmStatic
@RhinoRuntimeFunctionInterface @RhinoRuntimeFunctionInterface
fun load(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Any? = ensureArgumentsOnlyOne(args) { o -> fun load(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Any? = ensureArgumentsOnlyOne(args) { o ->
// require(o is String) { "Argument name for plugins.load must be a string" }
val name = coerceString(o) val name = coerceString(o)
val asPackageName = name.contains('.') && !name.matches(Regex(".+\\.js", IGNORE_CASE)) val asPackageName = name.contains('.') && !name.matches(Regex(".+\\.js", IGNORE_CASE))
when { when {

View File

@@ -1,6 +1,8 @@
package org.autojs.autojs.util package org.autojs.autojs.util
import android.util.Base64 import android.util.Base64
import java.io.File
import java.io.FileInputStream
import java.security.MessageDigest import java.security.MessageDigest
import java.security.NoSuchAlgorithmException import java.security.NoSuchAlgorithmException
@@ -26,6 +28,19 @@ object MD5Utils {
} }
} }
@JvmStatic
fun md5(file: File): String {
val buffer = ByteArray(1024)
val digest = MessageDigest.getInstance("MD5")
FileInputStream(file).use { fis ->
var numRead: Int
while (fis.read(buffer).also { numRead = it } > 0) {
digest.update(buffer, 0, numRead)
}
}
return digest.digest().joinToString("") { "%02x".format(it) }
}
@JvmStatic @JvmStatic
fun toHash(text: String): String = try { fun toHash(text: String): String = try {
MessageDigest.getInstance("MD5") MessageDigest.getInstance("MD5")

View File

@@ -1,5 +1,5 @@
#Sun Jan 12 23:32:51 CST 2025 #Mon Jan 13 01:22:59 CST 2025
BUILD_TIME=1736695971805 BUILD_TIME=1736702579820
COMPILE_SDK_VERSION=34 COMPILE_SDK_VERSION=34
JAVA_VERSION=23 JAVA_VERSION=23
JAVA_VERSION_MIN_RADICAL=0 JAVA_VERSION_MIN_RADICAL=0
@@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
TARGET_SDK_VERSION=34 TARGET_SDK_VERSION=34
TARGET_SDK_VERSION_INRT=29 TARGET_SDK_VERSION_INRT=29
VERSION_BUILD=2966 VERSION_BUILD=2967
VERSION_NAME=6.6.2 Alpha VERSION_NAME=6.6.2 Alpha
VSCODE_EXT_REQUIRED_VERSION=1.0.8 VSCODE_EXT_REQUIRED_VERSION=1.0.8