Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.core.content.pm.ShortcutManagerCompat
import com.github.kr328.clash.common.util.componentName
import com.github.kr328.clash.design.AppSettingsDesign
import com.github.kr328.clash.design.model.Behavior
import com.github.kr328.clash.design.store.UiStore.Companion.mainActivityAlias
import com.github.kr328.clash.service.store.ServiceStore
import com.github.kr328.clash.util.ApplicationObserver
import kotlinx.coroutines.isActive
Expand Down Expand Up @@ -70,7 +71,7 @@ class AppSettingsActivity : BaseActivity<AppSettingsDesign>(), Behavior {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
}
packageManager.setComponentEnabledSetting(
ComponentName(this, mainActivityAlias),
mainActivityAlias,
newState,
PackageManager.DONT_KILL_APP
)
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/java/com/github/kr328/clash/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,3 @@ class MainActivity : BaseActivity<MainDesign>() {
}
}
}

val mainActivityAlias = "${MainActivity::class.java.name}Alias"
13 changes: 5 additions & 8 deletions app/src/main/java/com/github/kr328/clash/MainApplication.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.github.kr328.clash

import android.app.Application
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.github.kr328.clash.common.Global
import com.github.kr328.clash.common.compat.currentProcessName
import com.github.kr328.clash.common.constants.Intents
import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.design.store.UiStore
import com.github.kr328.clash.remote.Remote
import com.github.kr328.clash.service.util.sendServiceRecreated
import com.github.kr328.clash.util.clashDir
Expand All @@ -22,6 +21,8 @@ import com.github.kr328.clash.design.R as DesignR

@Suppress("unused")
class MainApplication : Application() {
private val uiStore by lazy(LazyThreadSafetyMode.NONE) { UiStore(this) }

override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)

Expand All @@ -45,12 +46,8 @@ class MainApplication : Application() {
}

private fun setupShortcuts() {
val aliasState = packageManager.getComponentEnabledSetting(
ComponentName(this, mainActivityAlias)
)
if (aliasState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED &&
aliasState != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
) {
if (uiStore.hideAppIcon) {
// Prevent launcher activity not found.
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.kr328.clash.design.store

import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
import com.github.kr328.clash.common.store.Store
import com.github.kr328.clash.common.store.asStoreProvider
import com.github.kr328.clash.core.model.ProxySort
Expand All @@ -27,7 +29,11 @@ class UiStore(context: Context) {

var hideAppIcon: Boolean by store.boolean(
key = "hide_app_icon",
defaultValue = false
defaultValue = context.packageManager.getComponentEnabledSetting(context.mainActivityAlias)
.let { state ->
state != PackageManager.COMPONENT_ENABLED_STATE_ENABLED &&
state != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
},
)
Comment on lines 30 to 37
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PackageManager.getComponentEnabledSetting(...) call is evaluated eagerly every time UiStore is constructed (because defaultValue is computed before it reaches the delegate). UiStore is created in non-UI paths (e.g., service start), so this adds an extra binder call even when hideAppIcon is never read. Consider deferring this lookup until the hide_app_icon key is actually read/missing (e.g., a specialized property getter, or a delegate that accepts a default-value supplier).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in eb1245b. Added a boolean(key, defaultValueProvider: () -> Boolean) overload to Store and a contains(key) method to StoreProvider/SharedPreferenceProvider. The defaultValueProvider lambda is only invoked when the key is absent from SharedPreferences, so the PackageManager.getComponentEnabledSetting() call is deferred until hideAppIcon is actually read and only runs when no stored preference exists.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted.


var hideFromRecents: Boolean by store.boolean(
Expand Down Expand Up @@ -74,5 +80,8 @@ class UiStore(context: Context) {

companion object {
private const val PREFERENCE_NAME = "ui"

val Context.mainActivityAlias: ComponentName
get() = ComponentName(this, "com.github.kr328.clash.MainActivityAlias")
}
}
Loading