Repository navigation
1.4.6
Summary / 概述
This PR prepares NekoBox 1.4.6 by resolving several critical lifecycle, concurrency, network resource, and UI defects, with a particular focus on decoupling drag-and-drop reordering in Router Groups to prevent cross-subscription order corruption, while retaining full drag-and-drop functionality for users.
本次提交为 NekoBox 1.4.6 准备版本,修复了多个关键的服务生命周期、并发控制、Socket 资源泄漏及 UI 缺陷;重点优化了路由分组(Router Group)下的拖拽排序机制,使路由分组内拖拽排序独立持久化,彻底解决了过去拖拽会打乱各节点在原本所属订阅中排序的问题,同时完整保留了路由分组的拖拽排序体验。
Key Changes / 主要变更
1. 🔀 Router Group Drag-and-Drop Order Decoupling (路由分组拖拽排序解耦)
- Problem: Dragging nodes within a router group previously overwrote
proxy_entities.userOrder, corrupting the original sequence of profiles in their respective source subscription groups. - Solution:
- Added
updateUserOrderquery and@Transaction updateOrdersbatch update toRouterMember.Dao. - In
ConfigurationAdapter.move(), interceptedinRouterGroupModeto only reorder the in-memory item IDs without touchingProxyEntity.userOrder. - In
ConfigurationAdapter.commitMove(), persisted the reordered sequence intorouter_members.userOrderand notified sing-box service reload smoothly. - Seamlessly integrates with
RouterReconciler.kt, ensuring user-defined order in router groups is safely preserved across subscription refreshes.
- Added
2. 🛡️ Subscription Concurrency Lock Protection (订阅更新并发互斥锁保护)
- Problem: In
GroupUpdater.executeUpdate(), duplicate update attempts or user cancellation of warning dialogs threwCancellationExceptionviacancel(), causing caller scope failures and prematurely unlocking the running update mutex incatchblocks. - Solution: Replaced
cancel()withreturn@coroutineScope falseto prevent exception leakage and maintain strict mutex lifecycle.
3. 🌐 WebDAV Connection & Socket Leak Prevention (WebDAV OkHttp 连接防泄漏)
- Problem: In
WebDAVSettingsActivity,client.newCall().execute()calls for auth and directory creation were not closed, leaking OkHttp sockets and connection pool resources. - Solution: Wrapped both network calls in Kotlin's
.use { response -> ... }blocks to ensure deterministic socket closing.
4. 🔄 ViewPager2 Memory Leak & UI Lifecycle Fixes (Fragment 视图生命周期与内存泄漏修复)
- Problem: In
ConfigurationFragment.GroupFragment, listeners were registered inonViewCreated()but only removed inonDestroy(). In ViewPager2, swiping pages out callsonDestroyView()while keeping the fragment instance, accumulating duplicate listeners and leaking views. Furthermore,routerGroupwas not parcelled across screen rotations. - Solution:
- Added
onDestroyView()to unregisterProfileManagerandGroupManagerlisteners, detach touch helpers, and clean up adapters. - Properly parcelled and restored
routerGroupinonSaveInstanceStateandonViewStateRestored. - Optimized
reloadProfiles()in router group mode by replacing the N+1getById()loop with a single batchgetEntities(memberIds)query.
- Added
5. 🔒 libcore Core Access Mutex & Lifecycle Check (Go sing-box 核心线程安全加锁)
- Problem:
SelectOutboundandSelectOutboundForinlibcore/box.golackedb.access.Lock()andb.statechecks, risking data races or nil dereferences during core stop or reload. - Solution: Acquired
b.access.Lock()and verifiedb.state == 1before accessing selectors and outbounds, matchingCurrentOutboundFor.
6. ⚠️ Router Group Deletion Confirmation Dialog (路由分组删除防误触)
- Added
MaterialAlertDialogBuilderconfirmation dialog before executing router group deletion inRouterGroupSettingsActivity.
7. 🧹 Post-Import Invalidation Cleanup (备份恢复后悬空数据清理)
- In
BackupFragment.finishImport(), automatically invokedSagerDatabase.routerGroupDao.clearInvalidSelections()andGroupManager.cleanupDanglingRouterMembers()after restoring router groups to prevent dangling node IDs.
8. ⚡ Traffic Looper & Version Bump (流量轮询节流与版本升级)
- Optimized
TrafficLoopersampling intervals and background notifications. - Bumped version to
1.4.6(versionCode:49) innb4a.properties.
Compatibility & Database Schema / 兼容性与数据库
- Room Database Schema: Kept at Version 10 (
SagerDatabase.kt). No migration required. - RuleEntity:
RuleEntity.routerGroupIdremains@IgnoredOnParcelto preserve legacy Android Parcel binary compatibility. - Native ABI: Verified full compatibility with
libcore.aarandlibhev-socks5-tunnel.soacrossarm64-v8a,armeabi-v7a,x86, andx86_64.
Verification & Testing / 验证与测试结果
-
./gradlew.bat testOssDebugUnitTest --offlinepassed (all 35 tasks successful). -
./gradlew.bat compileOssDebugKotlin --offlinepassed (0 compilation errors). -
:app:verifyLibcoreand:app:verifyOssDebugLibcoreCallerspassed. - Packaged full set of 1.4.6 debug APKs under
app/build/outputs/apk/oss/debug/.