Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: lifecycle event emit on destroy state causing crash #280 #297

Merged
merged 2 commits into from
Jan 9, 2024

Conversation

DevSrSouza
Copy link
Collaborator

This PR fixes #280

@DevSrSouza
Copy link
Collaborator Author

For testing the solution, you can apply this git patch, open the sample app and go to Basic Navigation flow.

diff --git a/samples/android/build.gradle.kts b/samples/android/build.gradle.kts
index 3dcaa77..9406b66 100644
--- a/samples/android/build.gradle.kts
+++ b/samples/android/build.gradle.kts
@@ -15,6 +15,7 @@ android {
     defaultConfig {
         applicationId = "cafe.adriel.voyager.sample"
     }
+    dataBinding.enable = true
 }
 
 kapt {
@@ -49,5 +50,17 @@ dependencies {
     implementation(libs.hilt.android)
     kapt(libs.hilt.compiler)
 
+    implementation("androidx.core:core-ktx:1.9.0")
+    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
+    implementation("androidx.activity:activity-compose:1.7.2")
+    implementation(platform("androidx.compose:compose-bom:2023.10.01"))
+    implementation("androidx.compose.ui:ui")
+    implementation("androidx.compose.ui:ui-graphics")
+    implementation("androidx.compose.ui:ui-tooling-preview")
+    implementation("androidx.compose.material3:material3")
+    debugImplementation("androidx.compose.ui:ui-tooling")
+    debugImplementation("androidx.compose.ui:ui-test-manifest")
+    implementation("androidx.compose.ui:ui-viewbinding")
+
     debugImplementation(libs.leakCanary)
 }
diff --git a/samples/android/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt b/samples/android/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt
index babfc12..3135fae 100644
--- a/samples/android/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt
+++ b/samples/android/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt
@@ -4,7 +4,31 @@ import android.os.Bundle
 import android.util.Log
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.Button
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.compose.ui.viewinterop.AndroidViewBinding
+import cafe.adriel.voyager.core.screen.Screen
+import cafe.adriel.voyager.core.screen.ScreenKey
+import cafe.adriel.voyager.core.screen.uniqueScreenKey
+import cafe.adriel.voyager.navigator.LocalNavigator
 import cafe.adriel.voyager.navigator.Navigator
+import cafe.adriel.voyager.navigator.currentOrThrow
+import cafe.adriel.voyager.sample.databinding.LayoutDataBindingBinding
+import cafe.adriel.voyager.transitions.SlideTransition
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
 
 class BasicNavigationActivity : ComponentActivity() {
 
@@ -12,13 +36,59 @@ class BasicNavigationActivity : ComponentActivity() {
         super.onCreate(savedInstanceState)
 
         setContent {
-            Navigator(
-                screen = BasicNavigationScreen(index = 0),
-                onBackPressed = { currentScreen ->
-                    Log.d("Navigator", "Pop screen #${(currentScreen as BasicNavigationScreen).index}")
-                    true
+            SlideNavigator(InitialScreen())
+        }
+    }
+}
+
+@Composable
+private fun SlideNavigator(navScreen: Screen) {
+    Navigator(navScreen) { navigator ->
+        SlideTransition(navigator)
+    }
+}
+
+
+class InitialScreen : Screen {
+    override val key: ScreenKey = uniqueScreenKey
+
+    @Composable
+    override fun Content() {
+        val navigator = LocalNavigator.currentOrThrow
+        Button(onClick = { navigator.push(Screen1()) }) {
+            Text(text = "Push new Screen")
+        }
+    }
+}
+
+class Screen1 : Screen {
+    override val key: ScreenKey = uniqueScreenKey
+
+    @Composable
+    override fun Content() {
+        Box(modifier = Modifier.fillMaxSize()) {
+            var show by remember { mutableStateOf(false) }
+            LaunchedEffect(key1 = Unit) {
+                while (isActive) {
+                    delay(250)
+                    show = !show
+                }
+            }
+            if (!show) {
+                CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
+            } else {
+                val lifecycleOwner = LocalLifecycleOwner.current
+                AndroidViewBinding(
+                    factory = { inflater, parent, attachToParent ->
+                        LayoutDataBindingBinding.inflate(inflater, parent, attachToParent)
+                            .apply {
+                                this.lifecycleOwner = lifecycleOwner
+                            }
+                    },
+                ) {
+                    this.text = "Show: $show"
                 }
-            )
+            }
         }
     }
 }
diff --git a/samples/android/src/main/res/layout/layout_data_binding.xml b/samples/android/src/main/res/layout/layout_data_binding.xml
new file mode 100644
index 0000000..344c4d6
--- /dev/null
+++ b/samples/android/src/main/res/layout/layout_data_binding.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <data>
+        <variable
+            name="text"
+            type="String" />
+    </data>
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@{text}" />
+
+</layout>

@DevSrSouza DevSrSouza changed the title fix: event mission on destroy state #280 fix: event emit on destroy state #280 Jan 9, 2024
@DevSrSouza DevSrSouza merged commit d7dbda9 into main Jan 9, 2024
1 check passed
@DevSrSouza DevSrSouza deleted the fix/emiting-wrong-lifecycle-state branch January 9, 2024 22:03
@Kashif-E
Copy link
Contributor

@DevSrSouza can we get an alpha release for this?

@DevSrSouza DevSrSouza changed the title fix: event emit on destroy state #280 fix: lifecycle event emit on destroy state causing crash #280 Jan 10, 2024
@DevSrSouza
Copy link
Collaborator Author

@Kashif-E published in 1.1.0-alpha02

@Kashif-E
Copy link
Contributor

Thanks @DevSrSouza

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crashing with java.lang.IllegalStateException: no event up from DESTROYED
2 participants