6.7.0 - Alpha19 - Fine tuning

This commit is contained in:
SuperMonster003
2026-02-04 13:36:49 +08:00
parent 32533afbf3
commit 140870b5ec
9 changed files with 101 additions and 86 deletions

View File

@@ -39,18 +39,21 @@ import java.util.concurrent.atomic.AtomicReference
* Transformed by SuperMonster003 on Oct 19, 2022.
* Modified by OpenAI ChatGPT (GPT-5.2 Thinking) as of Jan 20, 2026.
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 1, 2026.
* Modified by SuperMonster003 as of Feb 1, 2026.
* Modified by SuperMonster003 as of Feb 3, 2026.
*/
object DialogUtils {
private const val TAG = "DialogUtils"
@JvmStatic
fun MaterialDialog.Builder.showAdaptive() = build().showAdaptive()
fun <T : MaterialDialog.Builder> T.showAdaptive(): MaterialDialog = build().showAdaptive()
@JvmStatic
fun <T : MaterialDialog.Builder> T.showAdaptiveOrNull(): MaterialDialog? = build()?.showAdaptive()
@JvmStatic
@Suppress("DEPRECATION")
fun MaterialDialog.showAdaptive() = showDialog(this)
fun <T : MaterialDialog> T.showAdaptive(): T = showDialog(this)
/**
* Show this [MaterialDialog] in a context-safe way.
@@ -92,7 +95,7 @@ object DialogUtils {
@JvmOverloads
@Deprecated("Use showAdaptive instead.", ReplaceWith("showAdaptive(dialog, focusable)"))
@ReservedForCompatibility
fun showDialog(dialog: MaterialDialog, focusable: Boolean = true): MaterialDialog {
fun <T : MaterialDialog> showDialog(dialog: T, focusable: Boolean = true): T {
runOnMain {
// Prevent duplicated show.
// zh-CN: 防止重复 show().
@@ -189,39 +192,18 @@ object DialogUtils {
return dialog
}
/**
* Build dialog on the main thread and return it.
*
* Note:
* - MaterialDialog.Builder.build() may internally create Android Dialog/Handler.
* - Building on a background thread can crash with "Can't create handler inside thread ...".
*
* zh-CN:
*
* 在主线程 build 对话框并返回实例.
*
* 注:
* - MaterialDialog.Builder.build() 内部可能创建 Android Dialog/Handler.
* - 在后台线程 build 可能触发 "Can't create handler inside thread ..." 崩溃.
*/
@JvmStatic
fun buildAdaptive(builder: MaterialDialog.Builder): MaterialDialog {
@Suppress("UNCHECKED_CAST")
return buildAdaptive { builder.build() }
}
/**
* Build dialog on the main thread by a callable factory.
*
* zh-CN: 通过 callable 工厂在主线程 build 对话框.
*/
@JvmStatic
fun buildAdaptive(factory: Callable<MaterialDialog>): MaterialDialog {
fun <T : MaterialDialog> buildAdaptive(factory: Callable<T>): T {
if (Looper.getMainLooper() == Looper.myLooper()) {
return factory.call()
}
val ref = AtomicReference<MaterialDialog>()
val ref = AtomicReference<T>()
val err = AtomicReference<Throwable?>()
val latch = CountDownLatch(1)
@@ -245,21 +227,34 @@ object DialogUtils {
return ref.get() ?: throw RuntimeException("buildAdaptive: dialog is null (timeout or build failed)")
}
/**
* Build and show dialog on the main thread, then return the dialog instance.
* Use this when the caller might be running on a background thread.
*
* zh-CN:
*
* 在主线程 build 并 show 对话框, 然后返回对话框实例.
* 当调用方可能运行在后台线程时使用该方法.
*/
@JvmStatic
@JvmOverloads
fun buildAndShowAdaptive(builder: MaterialDialog.Builder, focusable: Boolean = true): MaterialDialog {
val dialog = buildAdaptive(builder)
@Suppress("DEPRECATION")
return showDialog(dialog, focusable)
fun <T : MaterialDialog> buildAdaptiveOrNull(factory: Callable<T?>): T? {
if (Looper.getMainLooper() == Looper.myLooper()) {
return factory.call()
}
val ref = AtomicReference<T?>()
val err = AtomicReference<Throwable?>()
val latch = CountDownLatch(1)
GlobalAppContext.post {
try {
ref.set(factory.call())
} catch (t: Throwable) {
err.set(t)
Log.w(TAG, "buildAdaptiveOrNull: failed", t)
} finally {
latch.countDown()
}
}
// Wait a bit to avoid infinite blocking in background threads.
// zh-CN: 设置等待超时以避免后台线程无限阻塞.
latch.await(5, TimeUnit.SECONDS)
err.get()?.let { throw RuntimeException(it) }
return ref.get()
}
/**
@@ -268,10 +263,32 @@ object DialogUtils {
* zh-CN: 使用 callable 工厂在主线程 build 并 show 对话框, 然后返回实例.
*/
@JvmStatic
@JvmOverloads
fun buildAndShowAdaptive(factory: Callable<MaterialDialog>, focusable: Boolean = true): MaterialDialog {
@Suppress("DEPRECATION")
fun <T : MaterialDialog> buildAndShowAdaptive(factory: Callable<T>): T {
return buildAndShowAdaptive(factory, true)
}
/**
* Build and show dialog on the main thread with a callable factory, then return the instance.
*
* zh-CN: 使用 callable 工厂在主线程 build 并 show 对话框, 然后返回实例.
*/
@JvmStatic
@Suppress("DEPRECATION")
fun <T : MaterialDialog> buildAndShowAdaptive(factory: Callable<T>, focusable: Boolean): T {
val dialog = buildAdaptive(factory)
@Suppress("DEPRECATION")
return showDialog(dialog, focusable)
}
@JvmStatic
@Suppress("DEPRECATION")
fun <T : MaterialDialog> buildAndShowAdaptiveOrNull(factory: Callable<T?>): T? =
buildAndShowAdaptiveOrNull(factory, true)
@JvmStatic
@Suppress("DEPRECATION")
fun <T : MaterialDialog> buildAndShowAdaptiveOrNull(factory: Callable<T?>, focusable: Boolean): T? {
val dialog = buildAdaptiveOrNull(factory) ?: return null
return showDialog(dialog, focusable)
}
@@ -468,8 +485,8 @@ object DialogUtils {
fun MaterialDialog.applyProgressThemeColorTintLists(): MaterialDialog = also {
val progressBar = progressBar ?: return@also
val bgColor = context.getColor(R.color.dialog_progress_gray_background_tint)
val fgColor = ColorUtils.adjustColorForContrast(bgColor, ThemeColorManager.colorPrimary, 2.3)
val fgColor = ColorUtils.adjustColorForContrast(context.getColor(R.color.dialog_progress_gray_background_tint), ThemeColorManager.colorPrimary, 2.3)
val bgColor = ColorUtils.applyAlpha(fgColor, 0.2)
progressBar.setProgressTintList(ColorStateList.valueOf(fgColor))
progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(bgColor))

View File

@@ -19,6 +19,7 @@ import org.autojs.autojs.util.MaterialDialogUtils.widgetThemeColor
import org.autojs.autojs.pluginclient.DevPluginService
import org.autojs.autojs.pluginclient.JsonSocketClient
import org.autojs.autojs.ui.common.NotAskAgainDialog
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs.util.Observers
import org.autojs.autojs.util.ThreadUtils.runOnMain
import org.autojs.autojs.util.ViewUtils
@@ -229,6 +230,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) {
dialog.inputEditText?.setText(text)
validateAndConnectToRemoteServer(dialog)
}
.choiceWidgetThemeColor()
.itemsLongCallback { dHistories, _, _, text ->
MaterialDialog.Builder(context)
.title(R.string.text_prompt)

View File

@@ -14,6 +14,7 @@ import kotlinx.coroutines.launch
import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs.ui.widget.SearchViewItem
import org.autojs.autojs.util.IntentUtils.startSafely
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs.util.ViewUtils.onceGlobalLayout
import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance
@@ -135,6 +136,7 @@ class PluginCenterActivity : BaseActivity() {
else -> Unit
}
}
.choiceWidgetThemeColor()
.negativeText(R.string.text_cancel)
.negativeColorRes(R.color.dialog_button_default)
.show()
@@ -167,6 +169,7 @@ class PluginCenterActivity : BaseActivity() {
else -> Unit
}
}
.choiceWidgetThemeColor()
.negativeText(R.string.text_cancel)
.negativeColorRes(R.color.dialog_button_default)
.show()

View File

@@ -17,6 +17,7 @@ import org.autojs.autojs.execution.SimpleScriptExecutionListener;
import org.autojs.autojs.lang.ThreadCompat;
import org.autojs.autojs.runtime.ScriptRuntime;
import org.autojs.autojs.runtime.api.Console;
import org.autojs.autojs.runtime.api.augment.engines.Engines;
import org.autojs.autojs.runtime.exception.ScriptInterruptedException;
import org.autojs.autojs.script.JavaScriptSource;
import org.autojs.autojs.script.ScriptSource;
@@ -66,6 +67,7 @@ public class ScriptEngineService {
if (execution.getEngine() instanceof JavaScriptEngine) {
((JavaScriptEngine) execution.getEngine()).getRuntime().console.setTitle(scriptSource.getName());
}
emitEngineEvent("start", execution.getEngine());
mGlobalConsole.verbose(MessageFormat.format("{0} [{1}].", getLanguageContext().getString(R.string.text_start_running), scriptSource.getElegantPath()));
}
@@ -75,26 +77,34 @@ public class ScriptEngineService {
}
private void onFinish(ScriptExecution execution) {
/* Empty function body. */
var engine = execution.getEngine();
emitEngineEvent("finish", engine);
emitEngineEvent("exit", engine);
emitEngineEvent("stop", engine);
}
@Override
public void onException(ScriptExecution execution, Throwable e) {
Log.d(TAG, "onException");
e.printStackTrace();
var engine = execution.getEngine();
emitEngineEvent("exception", engine, e);
emitEngineEvent("error", engine, e);
onFinish(execution);
String message = null;
if (!ScriptInterruptedException.causedByInterrupt(e)) {
message = e.getMessage();
if (execution.getEngine() instanceof JavaScriptEngine engine) {
engine.getRuntime().console.error(e);
if (engine instanceof JavaScriptEngine scriptEngine) {
scriptEngine.getRuntime().console.error(e);
}
}
if (execution.getEngine() instanceof JavaScriptEngine engine) {
if (engine instanceof JavaScriptEngine scriptEngine) {
Throwable uncaughtException = engine.getUncaughtException();
if (uncaughtException != null) {
message = uncaughtException.getMessage();
engine.getRuntime().console.error(uncaughtException);
scriptEngine.getRuntime().console.error(uncaughtException);
}
}
if (message != null) {
@@ -211,6 +221,15 @@ public class ScriptEngineService {
return mScriptExecutions.get(id);
}
private void emitEngineEvent(String eventName, ScriptEngine<? extends ScriptSource> engine, Object... args) {
for (ScriptEngine<?> scriptEngine : getEngines()) {
if (scriptEngine instanceof JavaScriptEngine jsEngine) {
ScriptRuntime runtime = jsEngine.getRuntime();
Engines.emit(runtime, eventName, engine, args);
}
}
}
public static void setInstance(ScriptEngineService service) {
if (sInstance != null) {
throw new IllegalStateException();

View File

@@ -2,17 +2,11 @@ package org.autojs.autojs.execution;
import org.autojs.autojs.AutoJs;
import org.autojs.autojs.core.pref.Language;
import org.autojs.autojs.engine.JavaScriptEngine;
import org.autojs.autojs.engine.ScriptEngine;
import org.autojs.autojs.runtime.ScriptRuntime;
import org.autojs.autojs.runtime.api.Console;
import org.autojs.autojs.runtime.api.augment.engines.Engines;
import org.autojs.autojs.script.ScriptSource;
import org.autojs.autojs6.R;
import java.util.List;
import java.util.stream.Collectors;
import static org.autojs.autojs.util.StringUtils.str;
/**
@@ -26,9 +20,6 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
@Override
public void onStart(ScriptExecution execution) {
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("start", engine);
engine.setTag(ENGINE_TAG_START_TIME, System.currentTimeMillis());
}
@@ -39,11 +30,6 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
private void onFinish(ScriptExecution execution) {
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("finish", engine);
emitEngineEvent("exit", engine);
emitEngineEvent("stop", engine);
Long startTime = (Long) engine.getTag(ENGINE_TAG_START_TIME);
if (startTime != null) {
printSeconds(execution, startTime);
@@ -60,27 +46,6 @@ public class ScriptExecutionGlobalListener implements ScriptExecutionListener {
@Override
public void onException(ScriptExecution execution, Throwable e) {
ScriptEngine<? extends ScriptSource> engine = execution.getEngine();
emitEngineEvent("exception", engine, e);
emitEngineEvent("error", engine, e);
onFinish(execution);
}
private void emitEngineEvent(String eventName, ScriptEngine<? extends ScriptSource> engine, Object... args) {
List<JavaScriptEngine> jsEngines = AutoJs.getInstance()
.getScriptEngineService()
.getEngines()
.stream()
.filter(JavaScriptEngine.class::isInstance)
.map(JavaScriptEngine.class::cast)
.collect(Collectors.toList());
for (JavaScriptEngine jsEngine : jsEngines) {
ScriptRuntime runtime = jsEngine.getRuntime();
Engines.emit(runtime, eventName, engine, args);
}
}
}

View File

@@ -35,6 +35,7 @@ import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.Category
import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.DEFAULT_FILTER
import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.DEFAULT_VERSION_NAME
import org.autojs.autojs.util.IntentUtils.startSafely
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs.util.ProcessLogger
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance
@@ -208,6 +209,7 @@ class DisplayVersionHistoriesActivity : BaseActivity() {
}
true
}
.choiceWidgetThemeColor()
.show()
}

View File

@@ -25,6 +25,7 @@ import org.autojs.autojs.tool.SimpleObserver
import org.autojs.autojs.ui.filechooser.FileChooserDialogBuilder
import org.autojs.autojs.ui.main.MainActivity
import org.autojs.autojs.util.EnvironmentUtils
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs.util.WorkingDirectoryUtils
import org.autojs.autojs6.R
@@ -82,6 +83,7 @@ class WorkingDirectoryPreference : MaterialPreference {
.itemsCallback { _, _, _, text ->
mContentView.setText(text)
}
.choiceWidgetThemeColor()
.negativeText(R.string.dialog_button_back)
.showAdaptive()
}
@@ -128,6 +130,7 @@ class WorkingDirectoryPreference : MaterialPreference {
.showAdaptive()
}
}
.choiceWidgetThemeColor()
.negativeText(R.string.dialog_button_back)
.negativeColorRes(R.color.dialog_button_default)
.onNegative { dHistories, _ -> dHistories.dismiss() }

View File

@@ -38,6 +38,7 @@ import org.autojs.autojs.runtime.api.WrappedShizuku
import org.autojs.autojs.ui.enhancedfloaty.FloatyService
import org.autojs.autojs.ui.floating.FloatyWindowManger
import org.autojs.autojs.util.ContextUtils.findActivity
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs.util.StringUtils.key
import org.autojs.autojs6.R
import java.io.File
@@ -551,6 +552,7 @@ object IntentUtils {
.autoDismiss(false)
.show()
}
.choiceWidgetThemeColor()
.positiveText(R.string.dialog_button_dismiss)
.onPositive { dialog, _ -> dialog.dismiss() }
.cancelable(false)

View File

@@ -14,6 +14,7 @@ import org.autojs.autojs.core.pref.Pref.lastUpdatesPostponedTimestamp
import org.autojs.autojs.network.UpdateChecker
import org.autojs.autojs.network.UpdateChecker.PromptMode
import org.autojs.autojs.network.entity.VersionInfo
import org.autojs.autojs.util.MaterialDialogUtils.choiceWidgetThemeColor
import org.autojs.autojs6.R
/**
@@ -67,6 +68,7 @@ object UpdateUtils {
.autoDismiss(false)
.show()
}
.choiceWidgetThemeColor()
.neutralText(R.string.dialog_button_clear_items)
.neutralColorRes(R.color.dialog_button_warn)
.onNeutral { dialogParent, _ ->