From df4e232087ce59b6af052d61ced38bd1d1223c56 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 14 Aug 2024 19:58:32 +0800 Subject: [PATCH] Code Optimization --- .../kotlin/com/v2ray/ang/AngApplication.kt | 3 - .../kotlin/com/v2ray/ang/ui/MainActivity.kt | 122 ++++++++++-------- .../com/v2ray/ang/ui/MainRecyclerAdapter.kt | 41 +++--- .../kotlin/com/v2ray/ang/util/MmkvManager.kt | 6 +- .../com/v2ray/ang/viewmodel/MainViewModel.kt | 44 ++----- 5 files changed, 107 insertions(+), 109 deletions(-) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt index 6416d201d..516fe1ed4 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt @@ -17,9 +17,6 @@ class AngApplication : MultiDexApplication(), Configuration.Provider { application = this } - //var firstRun = false - // private set - override fun onCreate() { super.onCreate() diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt index 659482714..51b3fe691 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt @@ -28,7 +28,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.navigation.NavigationView import com.google.android.material.tabs.TabLayout import com.tbruyelle.rxpermissions3.RxPermissions -import com.tencent.mmkv.MMKV import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivityMainBinding @@ -55,8 +54,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } private val adapter by lazy { MainRecyclerAdapter(this) } - private val mainStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_MAIN, MMKV.MULTI_PROCESS_MODE) } - private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) } private val requestVpnPermission = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == RESULT_OK) { startV2Ray() @@ -91,7 +88,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList binding.fab.setOnClickListener { if (mainViewModel.isRunning.value == true) { Utils.stopVService(this) - } else if ((settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: "VPN") == "VPN") { + } else if ((MmkvManager.settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: "VPN") == "VPN") { val intent = VpnService.prepare(this) if (intent == null) { startV2Ray() @@ -121,7 +118,8 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList val toggle = ActionBarDrawerToggle( - this, binding.drawerLayout, binding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) + this, binding.drawerLayout, binding.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close + ) binding.drawerLayout.addDrawerListener(toggle) toggle.syncState() binding.navView.setNavigationItemSelectedListener(this) @@ -202,7 +200,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList fun startV2Ray() { if (isNetworkConnected) { - if (mainStorage?.decodeString(MmkvManager.KEY_SELECTED_SERVER).isNullOrEmpty()) { + if (MmkvManager.mainStorage?.decodeString(MmkvManager.KEY_SELECTED_SERVER).isNullOrEmpty()) { return } V2RayServiceManager.startV2Ray(this) @@ -216,10 +214,10 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList Utils.stopVService(this) } Observable.timer(500, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - startV2Ray() - } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + startV2Ray() + } } public override fun onResume() { @@ -259,46 +257,57 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList importQRcode(true) true } + R.id.import_clipboard -> { importClipboard() true } + R.id.import_manually_vmess -> { importManually(EConfigType.VMESS.value) true } + R.id.import_manually_vless -> { importManually(EConfigType.VLESS.value) true } + R.id.import_manually_ss -> { importManually(EConfigType.SHADOWSOCKS.value) true } + R.id.import_manually_socks -> { importManually(EConfigType.SOCKS.value) true } + R.id.import_manually_trojan -> { importManually(EConfigType.TROJAN.value) true } + R.id.import_manually_wireguard -> { importManually(EConfigType.WIREGUARD.value) true } + R.id.import_config_custom_clipboard -> { importConfigCustomClipboard() true } + R.id.import_config_custom_local -> { importConfigCustomLocal() true } + R.id.import_config_custom_url -> { importConfigCustomUrlClipboard() true } + R.id.import_config_custom_url_scan -> { importQRcode(false) true @@ -342,23 +351,24 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList R.id.del_all_config -> { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) - .setPositiveButton(android.R.string.ok) { _, _ -> - binding.pbWaiting.show() - lifecycleScope.launch(Dispatchers.IO) { - mainViewModel.removeAllServer() - launch(Dispatchers.Main) { - mainViewModel.reloadServerList() - binding.pbWaiting.hide() - } + .setPositiveButton(android.R.string.ok) { _, _ -> + binding.pbWaiting.show() + lifecycleScope.launch(Dispatchers.IO) { + mainViewModel.removeAllServer() + launch(Dispatchers.Main) { + mainViewModel.reloadServerList() + binding.pbWaiting.hide() } } - .setNegativeButton(android.R.string.no) {_, _ -> - //do noting - } - .show() + } + .setNegativeButton(android.R.string.no) { _, _ -> + //do noting + } + .show() true } - R.id.del_duplicate_config-> { + + R.id.del_duplicate_config -> { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) .setPositiveButton(android.R.string.ok) { _, _ -> binding.pbWaiting.show() @@ -390,12 +400,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } } - .setNegativeButton(android.R.string.no) {_, _ -> + .setNegativeButton(android.R.string.no) { _, _ -> //do noting } .show() true } + R.id.sort_by_test_results -> { binding.pbWaiting.show() lifecycleScope.launch(Dispatchers.IO) { @@ -407,10 +418,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } true } + else -> super.onOptionsItemSelected(item) } - private fun importManually(createConfigType : Int) { + private fun importManually(createConfigType: Int) { startActivity( Intent() .putExtra("createConfigType", createConfigType) @@ -429,16 +441,16 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList // .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), requestCode) // } catch (e: Exception) { RxPermissions(this) - .request(Manifest.permission.CAMERA) - .subscribe { - if (it) - if (forConfig) - scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) - else - scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) + .request(Manifest.permission.CAMERA) + .subscribe { + if (it) + if (forConfig) + scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) else - toast(R.string.toast_permission_denied) - } + scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) + else + toast(R.string.toast_permission_denied) + } // } return true } @@ -569,7 +581,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList /** * import config from sub */ - private fun importConfigViaSub() : Boolean { + private fun importConfigViaSub(): Boolean { // val dialog = AlertDialog.Builder(this) // .setView(LayoutProgressBinding.inflate(layoutInflater).root) // .setCancelable(false) @@ -625,19 +637,19 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList Manifest.permission.READ_EXTERNAL_STORAGE } RxPermissions(this) - .request(permission) - .subscribe { - if (it) { - try { - contentResolver.openInputStream(uri).use { input -> - importCustomizeConfig(input?.bufferedReader()?.readText()) - } - } catch (e: Exception) { - e.printStackTrace() + .request(permission) + .subscribe { + if (it) { + try { + contentResolver.openInputStream(uri).use { input -> + importCustomizeConfig(input?.bufferedReader()?.readText()) } - } else - toast(R.string.toast_permission_denied) - } + } catch (e: Exception) { + e.printStackTrace() + } + } else + toast(R.string.toast_permission_denied) + } } /** @@ -685,27 +697,33 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } - override fun onNavigationItemSelected(item: MenuItem): Boolean { // Handle navigation view item clicks here. when (item.itemId) { R.id.sub_setting -> { - requestSubSettingActivity.launch(Intent(this,SubSettingActivity::class.java)) + requestSubSettingActivity.launch(Intent(this, SubSettingActivity::class.java)) } + R.id.settings -> { - startActivity(Intent(this, SettingsActivity::class.java) - .putExtra("isRunning", mainViewModel.isRunning.value == true)) + startActivity( + Intent(this, SettingsActivity::class.java) + .putExtra("isRunning", mainViewModel.isRunning.value == true) + ) } + R.id.user_asset_setting -> { startActivity(Intent(this, UserAssetActivity::class.java)) } + R.id.promotion -> { Utils.openUri(this, "${Utils.decode(AppConfig.PromotionUrl)}?t=${System.currentTimeMillis()}") } + R.id.logcat -> { startActivity(Intent(this, LogcatActivity::class.java)) } - R.id.about-> { + + R.id.about -> { startActivity(Intent(this, AboutActivity::class.java)) } } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt index cc9a062f3..b1e891125 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt @@ -10,7 +10,6 @@ import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.google.gson.Gson -import com.tencent.mmkv.MMKV import com.v2ray.ang.AngApplication.Companion.application import com.v2ray.ang.AppConfig import com.v2ray.ang.R @@ -38,9 +37,6 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter by lazy { mActivity.resources.getStringArray(R.array.share_method) } @@ -71,13 +67,13 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter { holder.itemMainBinding.tvType.text = profile.configType.name } + else -> { holder.itemMainBinding.tvType.text = profile.configType.name.lowercase() } @@ -114,6 +112,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter { if (AngConfigManager.share2Clipboard(mActivity, guid) == 0) { mActivity.toast(R.string.toast_success) @@ -121,6 +120,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter shareFullContent(guid) else -> mActivity.toast("else") } @@ -132,7 +132,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter removeServer(guid, position) } - .setNegativeButton(android.R.string.no) {_, _ -> + .setNegativeButton(android.R.string.no) { _, _ -> //do noting } .show() @@ -159,9 +159,9 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter MainViewHolder(ItemRecyclerMainBinding.inflate(LayoutInflater.from(parent.context), parent, false)) + else -> FooterViewHolder(ItemRecyclerFooterBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } @@ -231,14 +232,14 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter { val json = mainStorage?.decodeString(KEY_ANG_CONFIGS) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt index cb9a736b7..517e2d8a6 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -12,7 +12,6 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.google.gson.Gson -import com.tencent.mmkv.MMKV import com.v2ray.ang.AngApplication import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig.ANG_PACKAGE @@ -40,34 +39,15 @@ import java.io.FileOutputStream import java.util.Collections class MainViewModel(application: Application) : AndroidViewModel(application) { - private val mainStorage by lazy { - MMKV.mmkvWithID( - MmkvManager.ID_MAIN, - MMKV.MULTI_PROCESS_MODE - ) - } - private val serverRawStorage by lazy { - MMKV.mmkvWithID( - MmkvManager.ID_SERVER_RAW, - MMKV.MULTI_PROCESS_MODE - ) - } - private val settingsStorage by lazy { - MMKV.mmkvWithID( - MmkvManager.ID_SETTING, - MMKV.MULTI_PROCESS_MODE - ) - } + private var serverList = MmkvManager.decodeServerList() + var subscriptionId: String = MmkvManager.settingsStorage.decodeString(AppConfig.CACHE_SUBSCRIPTION_ID, "") ?: "" - var serverList = MmkvManager.decodeServerList() - var subscriptionId: String = settingsStorage.decodeString(AppConfig.CACHE_SUBSCRIPTION_ID, "")?:"" - var keywordFilter: String = settingsStorage.decodeString(AppConfig.CACHE_KEYWORD_FILTER, "")?:"" - private set + //var keywordFilter: String = MmkvManager.settingsStorage.decodeString(AppConfig.CACHE_KEYWORD_FILTER, "")?:"" + private var keywordFilter = "" val serversCache = mutableListOf() val isRunning by lazy { MutableLiveData() } val updateListAction by lazy { MutableLiveData() } val updateTestResultAction by lazy { MutableLiveData() } - private val tcpingTestScope by lazy { CoroutineScope(Dispatchers.IO) } fun startListenBroadcast() { @@ -121,7 +101,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { config.fullConfig = Gson().fromJson(server, V2rayConfig::class.java) config.remarks = config.fullConfig?.remarks ?: System.currentTimeMillis().toString() val key = MmkvManager.encodeServerConfig("", config) - serverRawStorage?.encode(key, server) + MmkvManager.serverRawStorage?.encode(key, server) serverList.add(0, key) val profile = ProfileItem( configType = config.configType, @@ -142,7 +122,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { fun swapServer(fromPosition: Int, toPosition: Int) { Collections.swap(serverList, fromPosition, toPosition) Collections.swap(serversCache, fromPosition, toPosition) - mainStorage?.encode(KEY_ANG_CONFIGS, Gson().toJson(serverList)) + MmkvManager.mainStorage?.encode(KEY_ANG_CONFIGS, Gson().toJson(serverList)) } @Synchronized @@ -173,7 +153,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } - fun exportAllServer() : Int { + fun exportAllServer(): Int { val serverListCopy = if (subscriptionId.isNullOrEmpty()) { serverList @@ -242,12 +222,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { fun subscriptionIdChanged(id: String) { if (subscriptionId != id) { subscriptionId = id - settingsStorage.encode(AppConfig.CACHE_SUBSCRIPTION_ID, subscriptionId) + MmkvManager.settingsStorage.encode(AppConfig.CACHE_SUBSCRIPTION_ID, subscriptionId) reloadServerList() } } - fun getSubscriptions(context: Context) : Pair?, MutableList?> { + fun getSubscriptions(context: Context): Pair?, MutableList?> { val subscriptions = MmkvManager.decodeSubscriptions() if (subscriptionId.isNotEmpty() && !subscriptions.map { it.first }.contains(subscriptionId) @@ -273,7 +253,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { return -1 } - fun removeDuplicateServer() : Int { + fun removeDuplicateServer(): Int { val serversCacheCopy = mutableListOf>() for (it in serversCache) { val config = MmkvManager.decodeServerConfig(it.guid) ?: continue @@ -354,7 +334,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { fun filterConfig(keyword: String) { keywordFilter = keyword - settingsStorage.encode(AppConfig.CACHE_KEYWORD_FILTER, keywordFilter) + MmkvManager.settingsStorage.encode(AppConfig.CACHE_KEYWORD_FILTER, keywordFilter) reloadServerList() } @@ -395,4 +375,4 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } } } -} +} \ No newline at end of file