6.7.0 - Alpha6 - 升级并适配 Android SDK 版本 35 -> 36

This commit is contained in:
SuperMonster003
2025-09-26 16:49:12 +08:00
parent aced2c4150
commit ecb1c57ebc
24 changed files with 226 additions and 185 deletions

View File

@@ -14,6 +14,13 @@ plugins {
id("com.android.application")
id("com.google.devtools.ksp")
id("org.jetbrains.kotlin.android") /* kotlin("android") */
id("idea")
}
idea {
module {
excludeDirs.add(file("$rootDir/app/src/main/java/com/stardust/"))
}
}
val globalApplicationId = "org.autojs.autojs6"
@@ -40,13 +47,10 @@ dependencies /* Unclassified */ {
implementation(kotlin("reflect"))
// Androidx Core
implementation("androidx.core:core-ktx") {
because("Compatibility for Android Gradle plugin 8.2.2")
version {
strictly("1.15.0")
because("Exception on newer versions: Dependency 'androidx.core:core:1.16.0' requires Android Gradle plugin 8.6.0 or higher")
}
}
implementation(libs.core.ktx)
// Local Broadcast Manager
implementation(libs.localbroadcastmanager)
// LeakCanary
debugImplementation(libs.leakcanary)
@@ -343,27 +347,21 @@ dependencies /* View */ {
}
dependencies /* GitHub API */ {
// GitHub API
implementation(files("$rootDir/libs/github-api-1.306.jar"))
implementation("commons-io:commons-io") {
because("Compatibility for Android API Level < 26 (Android 8.0) [O]")
version {
strictly("2.8.0")
because("Exception on newer versions: 'NoClassDefFoundError: org.apache.commons.io.IObuildUtils'")
}
}
// Commons IO
// @Hint by SuperMonster003 on Sep 25, 2025.
// ! Strict version: "2.8.0".
// ! Compatibility for Android API Level < 26 (Android 8.0) [O].
// ! Exception on newer versions: 'NoClassDefFoundError: org.apache.commons.io.IObuildUtils'.
implementation(libs.commons.io)
implementation("com.fasterxml.jackson.core:jackson-databind") {
because("Compatibility for Android API Level < 26 (Android 8.0) [O]")
version {
strictly("2.13.4.2")
because("Exception on 2.14.x: 'No virtual method getParameterCount()I in class Ljava/lang/reflect/Method'")
}
}
// Jackson Databind
implementation(libs.jackson.databind)
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") {
because("Compatibility of java.time.* for Android API Level < 26 (Android 8.0) [O]")
}
// Desugar
coreLibraryDesugaring(libs.desugar)
}
dependencies /* MLKit */ {

View File

@@ -76,10 +76,10 @@ public class MainThreadProxy {
mThread.stop();
}
@Deprecated
public void stop(Throwable obj) {
mThread.stop(obj);
}
// @Deprecated
// public void stop(Throwable obj) {
// mThread.stop(obj);
// }
public void interrupt() {
mThread.interrupt();
@@ -93,24 +93,24 @@ public class MainThreadProxy {
return mThread.isInterrupted();
}
@Deprecated
public void destroy() {
mThread.destroy();
}
// @Deprecated
// public void destroy() {
// mThread.destroy();
// }
public boolean isAlive() {
return mThread.isAlive();
}
@Deprecated
public void suspend() {
mThread.suspend();
}
// @Deprecated
// public void suspend() {
// mThread.suspend();
// }
@Deprecated
public void resume() {
mThread.resume();
}
// @Deprecated
// public void resume() {
// mThread.resume();
// }
public void setPriority(int newPriority) {
mThread.setPriority(newPriority);
@@ -140,10 +140,10 @@ public class MainThreadProxy {
return Thread.enumerate(tarray);
}
@Deprecated
public int countStackFrames() {
return mThread.countStackFrames();
}
// @Deprecated
// public int countStackFrames() {
// return mThread.countStackFrames();
// }
public void join(long millis) throws InterruptedException {
mThread.join(millis);

View File

@@ -24,10 +24,10 @@ object AppOps {
.invoke(manager, permission, uid, packageName)
}
else -> permission.toString().let {
@Suppress("DEPRECATION")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
manager.unsafeCheckOpNoThrow(it, uid, packageName)
} else {
@Suppress("DEPRECATION")
manager.checkOpNoThrow(it, uid, packageName)
}
}

View File

@@ -78,10 +78,10 @@ public class MainThreadProxy {
mThread.stop();
}
@Deprecated
public void stop(Throwable obj) {
mThread.stop(obj);
}
// @Deprecated
// public void stop(Throwable obj) {
// mThread.stop(obj);
// }
public void interrupt() {
mThread.interrupt();
@@ -95,24 +95,24 @@ public class MainThreadProxy {
return mThread.isInterrupted();
}
@Deprecated
public void destroy() {
mThread.destroy();
}
// @Deprecated
// public void destroy() {
// mThread.destroy();
// }
public boolean isAlive() {
return mThread.isAlive();
}
@Deprecated
public void suspend() {
mThread.suspend();
}
// @Deprecated
// public void suspend() {
// mThread.suspend();
// }
@Deprecated
public void resume() {
mThread.resume();
}
// @Deprecated
// public void resume() {
// mThread.resume();
// }
public void setPriority(int newPriority) {
mThread.setPriority(newPriority);
@@ -142,10 +142,10 @@ public class MainThreadProxy {
return Thread.enumerate(tarray);
}
@Deprecated
public int countStackFrames() {
return mThread.countStackFrames();
}
// @Deprecated
// public int countStackFrames() {
// return mThread.countStackFrames();
// }
public void join(long millis) throws InterruptedException {
mThread.join(Math.max(0, millis));

View File

@@ -20,7 +20,7 @@ open class JsSwitch : SwitchCompat {
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun setOnCheckedChangeListener(listener: OnCheckedChangeListener?) {
super.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
super.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean ->
if (!mIgnoreCheckedChange) {
listener?.onCheckedChanged(buttonView, isChecked)
}

View File

@@ -953,15 +953,16 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
o.deleteProp("package")
if (!packageNameRaw.isJsNullish()) {
val packageName = when (packageNameRaw) {
is PresetApp -> packageNameRaw.packageName
else -> when (val packageNameStr = coerceString(packageNameRaw)) {
val packageName = when (val raw = packageNameRaw) {
is PresetApp -> raw.packageName
else -> when (val packageNameStr = coerceString(raw)) {
in presetPackageNames -> presetPackageNames[packageNameStr]!!
else -> packageNameStr
}
}
if (packageName != packageNameRaw) {
o.defineProp("packageName", packageName).also {
@Suppress("AssignedValueIsNeverRead")
packageNameRaw = packageName
}
}

View File

@@ -537,7 +537,7 @@ abstract class ColorSelectBaseActivity : BaseActivity() {
val normalizedQuery = normalizeForMatching(searchTerm)
colorItems.filter { colorItem ->
val colorHex = String.format("#%06X", 0xFFFFFF and getColor(colorItem.colorRes))
val enName by lazy { getLocalizedString(this@ColorSelectBaseActivity, colorItem.nameRes, Locale("en")) }
val enName by lazy { getLocalizedString(this@ColorSelectBaseActivity, colorItem.nameRes, Locale.forLanguageTag("en")) }
val localizedName by lazy { getString(colorItem.nameRes) }
when {
searchTerm.startsWith("#") -> {
@@ -569,6 +569,9 @@ abstract class ColorSelectBaseActivity : BaseActivity() {
}
private fun normalizeForMatching(input: String): String {
// Remove all non-letter and non-digit characters (e.g. spaces/brackets/slashes etc.).
// \p{L} matches any letter character in any language, \p{N} matches any digit.
// zh-CN:
// 去掉所有非字母或数字字符 (例如空格/括号/斜线等).
// \p{L} 表示任何语言的字母字符, \p{N} 表示数字.
return input.replace("[^\\p{L}\\p{N}]+".toRegex(), "")
@@ -586,8 +589,11 @@ abstract class ColorSelectBaseActivity : BaseActivity() {
}
private fun extractPatternFromQuery(query: String): String {
// 假设已检查过 isRegexSearch() == true
// 去掉最前和最后的斜杠
// Assuming isRegexSearch() == true has been checked.
// Remove the leading and trailing slashes.
// zh-CN:
// 假设已检查过 isRegexSearch() == true.
// 去掉最前和最后的斜杠.
return query.substring(1, query.length - 1)
}

View File

@@ -13,9 +13,11 @@ object ProcessLogger {
private val buffer = StringBuilder()
/* 用 SharedFlow 推送 "增量行". */
private val _flow = MutableSharedFlow<String>(extraBufferCapacity = 64)
val flow: SharedFlow<String> = _flow.asSharedFlow()
// Use SharedFlow to broadcast "incremental lines".
// zh-CN: 用 SharedFlow 推送 "增量行".
private val internalFlow = MutableSharedFlow<String>(extraBufferCapacity = 64)
val flow: SharedFlow<String> = internalFlow.asSharedFlow()
@Synchronized
fun dump(): String = buffer.toString()
@@ -28,7 +30,7 @@ object ProcessLogger {
val suffix = if (buffer.isNotEmpty()) "\n" else ""
val line = "$suffix${sdf.format(Date())}: $msg"
buffer.append(line)
_flow.tryEmit(line)
internalFlow.tryEmit(line)
}
}

View File

@@ -1,6 +1,6 @@
package org.autojs.autojs.util;
import static org.autojs.autojs.util.StringUtils.getStringByLocal;
import static org.autojs.autojs.util.StringUtils.getStringByLanguageTag;
import static org.autojs.autojs.util.StringUtils.key;
import static org.autojs.autojs.util.StringUtils.str;
@@ -22,9 +22,9 @@ public class RootUtils {
private static String runtimeOverriddenRootMode = RootMode.AUTO_DETECT.key;
public enum RootMode {
FORCE_ROOT(key(R.string.key_root_mode_force_root), getStringByLocal(R.string.entry_root_mode_force_root, "en")),
FORCE_NON_ROOT(key(R.string.key_root_mode_force_non_root), getStringByLocal(R.string.entry_root_mode_force_non_root, "en")),
AUTO_DETECT(key(R.string.key_root_mode_auto_detect), getStringByLocal(R.string.entry_root_mode_auto_detect, "en"));
FORCE_ROOT(key(R.string.key_root_mode_force_root), getStringByLanguageTag(R.string.entry_root_mode_force_root, "en")),
FORCE_NON_ROOT(key(R.string.key_root_mode_force_non_root), getStringByLanguageTag(R.string.entry_root_mode_force_non_root, "en")),
AUTO_DETECT(key(R.string.key_root_mode_auto_detect), getStringByLanguageTag(R.string.entry_root_mode_auto_detect, "en"));
public final String key;

View File

@@ -184,9 +184,9 @@ object StringUtils {
}
@JvmStatic
fun getStringByLocal(id: Int, locale: String): String {
fun getStringByLanguageTag(id: Int, locale: String): String {
val configuration = Configuration(globalAppContext.resources.configuration)
configuration.setLocale(Locale(locale))
configuration.setLocale(Locale.forLanguageTag(locale))
return globalAppContext.createConfigurationContext(configuration).resources.getString(id)
}