From be95e6a88e4a8181a3ec0390e8d0c5952989161b Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:28:34 +0800 Subject: [PATCH] Refactor subscription handling with SubscriptionCache --- .../com/v2ray/ang/dto/SubscriptionCache.kt | 6 +++++ .../com/v2ray/ang/handler/AngConfigManager.kt | 27 ++++++++++--------- .../java/com/v2ray/ang/handler/MmkvManager.kt | 7 ++--- .../v2ray/ang/handler/SubscriptionUpdater.kt | 6 ++--- .../com/v2ray/ang/ui/ServerGroupActivity.kt | 8 +++--- .../v2ray/ang/ui/SubSettingRecyclerAdapter.kt | 4 +-- .../com/v2ray/ang/viewmodel/MainViewModel.kt | 9 ++++--- .../ang/viewmodel/SubscriptionsViewModel.kt | 11 ++++---- 8 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionCache.kt diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionCache.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionCache.kt new file mode 100644 index 00000000..e6c4709f --- /dev/null +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionCache.kt @@ -0,0 +1,6 @@ +package com.v2ray.ang.dto + +data class SubscriptionCache( + val guid: String, + val subscription: SubscriptionItem +) \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt index 33311750..7f87dd05 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt @@ -9,6 +9,7 @@ import com.v2ray.ang.AppConfig.HY2 import com.v2ray.ang.R import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.ProfileItem +import com.v2ray.ang.dto.SubscriptionCache import com.v2ray.ang.dto.SubscriptionItem import com.v2ray.ang.fmt.CustomFmt import com.v2ray.ang.fmt.Hysteria2Fmt @@ -399,28 +400,28 @@ object AngConfigManager { * @param it The subscription item. * @return The number of configurations updated. */ - fun updateConfigViaSub(it: Pair): Int { + fun updateConfigViaSub(it: SubscriptionCache): Int { try { - if (TextUtils.isEmpty(it.first) - || TextUtils.isEmpty(it.second.remarks) - || TextUtils.isEmpty(it.second.url) + if (TextUtils.isEmpty(it.guid) + || TextUtils.isEmpty(it.subscription.remarks) + || TextUtils.isEmpty(it.subscription.url) ) { return 0 } - if (!it.second.enabled) { + if (!it.subscription.enabled) { return 0 } - val url = HttpUtil.toIdnUrl(it.second.url) + val url = HttpUtil.toIdnUrl(it.subscription.url) if (!Utils.isValidUrl(url)) { return 0 } - if (!it.second.allowInsecureUrl) { + if (!it.subscription.allowInsecureUrl) { if (!Utils.isValidSubUrl(url)) { return 0 } } Log.i(AppConfig.TAG, url) - val userAgent = it.second.userAgent + val userAgent = it.subscription.userAgent var configText = try { val httpPort = SettingsManager.getHttpPort() @@ -440,11 +441,11 @@ object AngConfigManager { if (configText.isEmpty()) { return 0 } - val count = parseConfigViaSub(configText, it.first, false) + val count = parseConfigViaSub(configText, it.guid, false) if (count > 0) { - it.second.lastUpdated = System.currentTimeMillis() - MmkvManager.encodeSubscription(it.first, it.second) - Log.i(AppConfig.TAG, "Subscription updated: ${it.second.remarks}, $count configs") + it.subscription.lastUpdated = System.currentTimeMillis() + MmkvManager.encodeSubscription(it.guid, it.subscription) + Log.i(AppConfig.TAG, "Subscription updated: ${it.subscription.remarks}, $count configs") } return count } catch (e: Exception) { @@ -481,7 +482,7 @@ object AngConfigManager { private fun importUrlAsSubscription(url: String): Int { val subscriptions = MmkvManager.decodeSubscriptions() subscriptions.forEach { - if (it.second.url == url) { + if (it.subscription.url == url) { return 0 } } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt index 7825b30c..697ea0b8 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/MmkvManager.kt @@ -7,6 +7,7 @@ import com.v2ray.ang.dto.AssetUrlItem import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.dto.RulesetItem import com.v2ray.ang.dto.ServerAffiliationInfo +import com.v2ray.ang.dto.SubscriptionCache import com.v2ray.ang.dto.SubscriptionItem import com.v2ray.ang.dto.WebDavConfig import com.v2ray.ang.util.JsonUtil @@ -309,15 +310,15 @@ object MmkvManager { * * @return The list of subscriptions. */ - fun decodeSubscriptions(): List> { + fun decodeSubscriptions(): List { initSubsList() - val subscriptions = mutableListOf>() + val subscriptions = mutableListOf() decodeSubsList().forEach { key -> val json = subStorage.decodeString(key) if (!json.isNullOrBlank()) { val item = JsonUtil.fromJson(json, SubscriptionItem::class.java)?: SubscriptionItem() - subscriptions.add(Pair(key, item)) + subscriptions.add(SubscriptionCache(key, item)) } } return subscriptions diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SubscriptionUpdater.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SubscriptionUpdater.kt index 35ad1e9b..182bb734 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SubscriptionUpdater.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SubscriptionUpdater.kt @@ -36,10 +36,10 @@ object SubscriptionUpdater { override suspend fun doWork(): Result { Log.i(AppConfig.TAG, "subscription automatic update starting") - val subs = MmkvManager.decodeSubscriptions().filter { it.second.autoUpdate } + val subs = MmkvManager.decodeSubscriptions().filter { it.subscription.autoUpdate } for (sub in subs) { - val subItem = sub.second + val subItem = sub.subscription if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notification.setChannelId(AppConfig.SUBSCRIPTION_UPDATE_CHANNEL) @@ -53,7 +53,7 @@ object SubscriptionUpdater { } notificationManager.notify(3, notification.build()) Log.i(AppConfig.TAG, "subscription automatic update: ---${subItem.remarks}") - AngConfigManager.updateConfigViaSub(Pair(sub.first, subItem)) + AngConfigManager.updateConfigViaSub(sub) notification.setContentText("Updating ${subItem.remarks}") } notificationManager.cancel(3) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerGroupActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerGroupActivity.kt index 676701f2..1ceb0745 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerGroupActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerGroupActivity.kt @@ -119,13 +119,13 @@ class ServerGroupActivity : BaseActivity() { val displayList = mutableListOf(getString(R.string.filter_config_all)) //none subIds.clear() subIds.add("") // index 0 => All - subs.forEach { (id, item) -> + subs.forEach { sub -> val name = when { - item.remarks.isNotBlank() -> item.remarks - else -> id + sub.subscription.remarks.isNotBlank() -> sub.subscription.remarks + else -> sub.guid } displayList.add(name) - subIds.add(id) + subIds.add(sub.guid) } val subAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, displayList) subAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt index 380bb3f9..40d5bd09 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt @@ -21,8 +21,8 @@ class SubSettingRecyclerAdapter( override fun onBindViewHolder(holder: MainViewHolder, position: Int) { val subscriptions = viewModel.getAll() - val subId = subscriptions[position].first - val subItem = subscriptions[position].second + val subId = subscriptions[position].guid + val subItem = subscriptions[position].subscription holder.itemSubSettingBinding.tvName.text = subItem.remarks holder.itemSubSettingBinding.tvUrl.text = subItem.url holder.itemSubSettingBinding.chkEnable.isChecked = subItem.enabled diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt index ab665cc4..7ab771ef 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -17,6 +17,7 @@ import com.v2ray.ang.R import com.v2ray.ang.dto.GroupMapItem import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.dto.ServersCache +import com.v2ray.ang.dto.SubscriptionCache import com.v2ray.ang.extension.serializable import com.v2ray.ang.extension.toastError import com.v2ray.ang.extension.toastSuccess @@ -179,7 +180,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { return AngConfigManager.updateConfigViaSubAll() } else { val subItem = MmkvManager.decodeSubscription(subscriptionId) ?: return 0 - return AngConfigManager.updateConfigViaSub(Pair(subscriptionId, subItem)) + return AngConfigManager.updateConfigViaSub(SubscriptionCache(subscriptionId, subItem)) } } @@ -273,7 +274,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { fun getSubscriptions(context: Context): List { val subscriptions = MmkvManager.decodeSubscriptions() if (subscriptionId.isNotEmpty() - && !subscriptions.map { it.first }.contains(subscriptionId) + && !subscriptions.map { it.guid }.contains(subscriptionId) ) { subscriptionIdChanged("") } @@ -285,8 +286,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { remarks = context.getString(R.string.filter_config_all) ) ) - subscriptions.forEach { (id, item) -> - groups.add(GroupMapItem(id = id, remarks = item.remarks)) + subscriptions.forEach { sub -> + groups.add(GroupMapItem(id = sub.guid, remarks = sub.subscription.remarks)) } return groups } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SubscriptionsViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SubscriptionsViewModel.kt index 41fe00da..a8c720ab 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SubscriptionsViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SubscriptionsViewModel.kt @@ -1,16 +1,17 @@ package com.v2ray.ang.viewmodel import androidx.lifecycle.ViewModel +import com.v2ray.ang.dto.SubscriptionCache import com.v2ray.ang.dto.SubscriptionItem import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.handler.SettingsChangeManager import com.v2ray.ang.handler.SettingsManager class SubscriptionsViewModel : ViewModel() { - private val subscriptions: MutableList> = + private val subscriptions: MutableList = MmkvManager.decodeSubscriptions().toMutableList() - fun getAll(): List> = subscriptions.toList() + fun getAll(): List = subscriptions.toList() fun reload() { subscriptions.clear() @@ -18,7 +19,7 @@ class SubscriptionsViewModel : ViewModel() { } fun remove(subId: String): Boolean { - val changed = subscriptions.removeAll { it.first == subId } + val changed = subscriptions.removeAll { it.guid == subId } if (changed) { MmkvManager.removeSubscription(subId) SettingsChangeManager.makeSetupGroupTab() @@ -27,9 +28,9 @@ class SubscriptionsViewModel : ViewModel() { } fun update(subId: String, item: SubscriptionItem) { - val idx = subscriptions.indexOfFirst { it.first == subId } + val idx = subscriptions.indexOfFirst { it.guid == subId } if (idx >= 0) { - subscriptions[idx] = Pair(subId, item) + subscriptions[idx] = SubscriptionCache(subId, item) MmkvManager.encodeSubscription(subId, item) } }