6.6.2 - Alpha - 修复 plugins.load; 优化 dex 文件加载方式 (issue #290)
This commit is contained in:
@@ -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": [
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user