启动意图后防止 MainActivity 视图模型重新创建

问题描述 投票:0回答:1

我正在使用 Jetpack compose,并在用户单击通知时触发 jetpack compose 深层链接。 这就是我在收到通知并且用户在应用程序中时创建通知的方式:

class NotificationService : FirebaseMessagingService() {


    override fun onMessageReceived(message: RemoteMessage) {

        message.notification?.let { notification ->
            val builder = NotificationCompat.Builder(this, "notification")
                .setSmallIcon(R.mipmap.ic_logo)
                .setContentTitle(notification.title)
                .setContentText(notification.body)
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT).apply {
                    message.data["category"]?.let { category ->
                        this.setContentIntent(notificationDeepLinkHandler(category = category))
                    }
                }
            with(NotificationManagerCompat.from(this)) {
                notify(1, builder.build())
            }
        }
    }
}

一切正常,但它会导致 MainActivity 重新创建,这很糟糕,因为这是我的 MainActivity:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        intent.extras?.getString("category")?.let {
            notificationDeepLinkHandler(it)
        }
        createNotificationChannel()
        setContent {
            MyTheme {
                val navController = rememberNavController()
                NavHost(navController = navController, startDestination = viewModel.destination) {
                    landingNavBuilder(navController = navController)
                    appNavBuilder()
                AuthenticationHandler(
                    navController = navController,
                    isUserAuthenticated = viewModel.isUserAuthenticated
                )
                SplashScreen()
            }
        }
    }

}

如前所述,我有一个可组合的

SplashScreen()
,每当用户打开应用程序时就会出现,并会在 2 秒后消失。它有自己的视图模型并且仅显示一次。但由于启动新意图会导致视图模型被破坏,因此它会再次出现。我该如何解决?

将标志设置为“SingleInstance”、“SingleTask”等方法没有帮助。

  <activity
            android:launchMode="singleTask"
            android:name=".main.presentation.activity.MainActivity"
            android:exported="true"
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <data android:host="deeplink" android:scheme="myapp" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

我尝试通过设置活动启动模式标志来改变行为,但没有帮助。

android kotlin android-jetpack-compose android-notifications deep-linking
1个回答
0
投票

为了防止由于深层链接而重新创建 MainActivity 时 SplashScreen 再次出现,您可以在 SplashScreen 可组合项中使用记住功能。 此函数允许您存储一个在重新组合时会被记住的值,因此 SplashScreen 只会显示一次。 首先,您需要创建一个记住值来存储 SplashScreen 是否已显示的状态。 您可以通过在 MainActivity 的 onCreate 方法中的 setContent 块之前添加以下代码来完成此操作:

kotlin
val splashScreenShown = remember { mutableStateOf(false) }

接下来,您需要修改 SplashScreen 可组合项以接受 MutableState 参数,该参数将用于在显示 SplashScreen 后更新splashScreenShown 的状态:

kotlin
@Composable
fun SplashScreen(splashScreenShown: MutableState<Boolean>) {
    // SplashScreen implementation
    // After the SplashScreen has been displayed, update the state:
    splashScreenShown.value = true
}

最后,需要根据splashScreenShown的值有条件地显示SplashScreen。您可以通过在 setContent 块内添加 if 语句来做到这一点:

kotlin
setContent {
    MyTheme {
        val navController = rememberNavController()
        NavHost(navController = navController, startDestination = viewModel.destination) {
            landingNavBuilder(navController = navController)
            appNavBuilder()
            AuthenticationHandler(
                navController = navController,
                isUserAuthenticated = viewModel.isUserAuthenticated
            )
            if (!splashScreenShown.value) {
                SplashScreen(splashScreenShown)
            }
        }
    }
}

通过这些更改,即使 MainActivity 由于深度链接而重新创建,SplashScreen 也只会显示一次。

© www.soinside.com 2019 - 2024. All rights reserved.