6.7.0 - Alpha19 - 修复文件管理器搜索结果展示后点击返回按钮或切换标签页面时可能导致应用崩溃的问题

This commit is contained in:
SuperMonster003
2026-02-03 01:32:37 +08:00
parent 1986353077
commit 3b488cfcf4
13 changed files with 47 additions and 10 deletions

View File

@@ -98,6 +98,7 @@
"Canvas 构造函数可接受的参数类型错误 _[`issue #402`](http://issues.autojs6.com/402)_",
"崩溃报告页面复制详细信息功能失效的问题",
"Android 16+ 自定义返回逻辑失效导致返回功能异常的问题",
"文件管理器搜索结果展示后点击返回按钮或切换标签页面时可能导致应用崩溃的问题",
"文件管理器删除项目文件夹后 UI 未能自动刷新的问题",
"任务面板列表项频繁变动时可能导致应用崩溃的问题",
"使用 \"三按钮\" 手势导航时导航栏前景色可能与夜间模式关联异常的问题",

View File

@@ -22,6 +22,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.autojs.autojs.core.pref.Pref.getInt
import org.autojs.autojs.core.pref.Pref.getLinkedList
@@ -84,8 +85,8 @@ import java.util.concurrent.Callable
/**
* Created by Stardust on Aug 21, 2017.
* Transformed by SuperMonster003 on Nov 23, 2024.
* Modified by JetBrains AI Assistant (GPT-5.2) as of Apr 20, 2026.
* Modified by SuperMonster003 as of Feb 2, 2026.
* Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 3, 2026.
* Modified by SuperMonster003 as of Feb 3, 2026.
*/
@SuppressLint("CheckResult", "NonConstantResourceId", "NotifyDataSetChanged")
open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRefreshListener, PopupMenu.OnMenuItemClickListener {
@@ -131,6 +132,10 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef
private val mPageStateHistories = Stack<ExplorerPageState>()
private var mDirectorySpanSize = 2
// Keep only one refresh chain running to avoid concurrent updates.
// zh-CN: 只允许一个刷新链路运行, 避免并发更新导致竞态问题.
private var mRefreshDisposable: Disposable? = null
// Unify action icon tint to match day/night theme, especially for overlay dialogs.
// zh-CN: 统一操作图标着色以匹配日/夜主题, 尤其用于 overlay 对话框场景.
private val mActionIconTint by lazy {
@@ -244,6 +249,11 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef
mExplorer?.unregisterChangeListener(this)
mPageStateHistories.clear()
binding = null
// Cancel pending refresh to avoid late UI updates and concurrent iterations.
// zh-CN: 取消未完成的刷新, 避免延迟 UI 更新以及并发遍历导致的问题.
mRefreshDisposable?.dispose()
mRefreshDisposable = null
}
override fun onRefresh() {
@@ -588,24 +598,41 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef
private fun refreshCurrentPage() {
val explorer = mExplorer ?: return
isRefreshing = true
explorer.fetchChildren(currentPage)
// Cancel the previous refresh to prevent multiple concurrent iterators on mutable data.
// zh-CN: 取消上一次刷新, 防止对可变数据产生多个并发迭代器.
mRefreshDisposable?.dispose()
mRefreshDisposable = explorer.fetchChildren(currentPage)
.subscribeOn(Schedulers.io())
.flatMapObservable { page: ExplorerPage? ->
currentPageState.page = page
Observable.fromIterable(page)
// Snapshot the iterable to avoid ConcurrentModificationException during iteration.
// zh-CN: 对可迭代对象做快照, 避免迭代期间被修改触发 ConcurrentModificationException.
val snapshot: List<ExplorerItem> = page?.toList() ?: emptyList()
Observable.fromIterable(snapshot)
}
.filter { f: ExplorerItem -> mFilter == null || mFilter!!.invoke(f) }
.collectInto(explorerItemManager.cloneConfig(), ExplorerItemManager::add)
.observeOn(Schedulers.computation())
.doOnSuccess(ExplorerItemManager::sort)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { newManager: ExplorerItemManager ->
.doFinally {
// Always end the refreshing state even when errors happen.
// zh-CN: 无论成功或失败都要结束刷新状态.
isRefreshing = false
}
.subscribe({ newManager: ExplorerItemManager ->
mProjectToolbar.updateVisibility()
explorerItemManager = newManager
notifyDataSetChanged()
isRefreshing = false
post { scrollToPositionImmediately() }
}
}, { e ->
Log.e(LOG_TAG, "refreshCurrentPage() failed", e)
showSnack(this, R.string.error_refresh_failed, true)
})
}
private fun scrollToPositionSmoothly() {

View File

@@ -1225,4 +1225,5 @@
<string name="text_write_secure_settings">اكتب إعدادات الأمان</string>
<string name="text_write_system_settings">كتابة إعدادات النظام</string>
<string name="text_xiaomi_background_popup_permission">النوافذ المنبثقة في الخلفية</string>
<string name="error_refresh_failed">فشل التحديث</string>
</resources>

View File

@@ -1220,4 +1220,5 @@
<string name="text_write_secure_settings">Write security settings</string>
<string name="text_write_system_settings">Write system settings</string>
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
<string name="error_refresh_failed">Refresh failed</string>
</resources>

View File

@@ -1223,4 +1223,5 @@
<string name="text_write_secure_settings">Escribir la configuración de seguridad</string>
<string name="text_write_system_settings">Escribir la configuración del sistema</string>
<string name="text_xiaomi_background_popup_permission">Ventanas emergentes en segundo plano</string>
<string name="error_refresh_failed">Error al actualizar</string>
</resources>

View File

@@ -1223,4 +1223,5 @@
<string name="text_write_secure_settings">Écrire les paramètres de sécurité</string>.
<string name="text_write_system_settings">Écrire les paramètres système</string>
<string name="text_xiaomi_background_popup_permission">Fenêtres contextuelles en arrière-plan</string>
<string name="error_refresh_failed">Echec de l\'actualisation</string>
</resources>

View File

@@ -1224,4 +1224,5 @@
<string name="text_write_secure_settings">セキュリティ設定の書き込み</string>
<string name="text_write_system_settings">システム設定の書き込み</string>
<string name="text_xiaomi_background_popup_permission">バックグラウンドでのポップアップ表示</string>
<string name="error_refresh_failed">更新に失敗しました</string>
</resources>

View File

@@ -1225,4 +1225,5 @@
<string name="text_write_secure_settings">보안 설정을 작성하십시오</string>
<string name="text_write_system_settings">시스템 설정을 작성하십시오</string>
<string name="text_xiaomi_background_popup_permission">백그라운드 팝업</string>
<string name="error_refresh_failed">새로고침에 실패했습니다</string>
</resources>

View File

@@ -5,7 +5,6 @@
<!-- Proofreader: [ JetBrains AI Assistant ] -->
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="apk_builder_build" tools:ignore="TypographyEllipsis">Строительство...</string>
<string name="apk_builder_clean" tools:ignore="TypographyEllipsis">Очистка...</string>
<string name="apk_builder_package" tools:ignore="TypographyEllipsis">Упаковка...</string>
@@ -1224,5 +1223,5 @@
<string name="text_write_secure_settings">Параметры безопасности записи</string>
<string name="text_write_system_settings">Запись системных настроек</string>
<string name="text_xiaomi_background_popup_permission">Всплывающие окна в фоне</string>
</resources>
<string name="error_refresh_failed">Не удалось обновить</string>
</resources>

View File

@@ -1221,4 +1221,5 @@
<string name="text_write_secure_settings">修改安全設置</string>
<string name="text_write_system_settings">修改系統設置</string>
<string name="text_xiaomi_background_popup_permission">後台彈出界面</string>
<string name="error_refresh_failed">刷新失敗</string>
</resources>

View File

@@ -1221,4 +1221,5 @@
<string name="text_write_secure_settings">修改安全設定</string>
<string name="text_write_system_settings">修改系統設定</string>
<string name="text_xiaomi_background_popup_permission">後臺彈出介面</string>
<string name="error_refresh_failed">刷新失敗</string>
</resources>

View File

@@ -1221,4 +1221,5 @@
<string name="text_write_secure_settings">修改安全设置</string>
<string name="text_write_system_settings">修改系统设置</string>
<string name="text_xiaomi_background_popup_permission">后台弹出界面</string>
<string name="error_refresh_failed">刷新失败</string>
</resources>

View File

@@ -1481,4 +1481,5 @@
<string name="text_write_secure_settings">Write security settings</string>
<string name="text_write_system_settings">Write system settings</string>
<string name="text_xiaomi_background_popup_permission">Display pop-up windows while running in the background</string>
<string name="error_refresh_failed">Refresh failed</string>
</resources>