I'm making a password entry overlay in my Android app when someone tries to open the selected app, but i got this error:
FATAL EXCEPTION: main
Process: com.example, PID: 10078
java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from androidx.compose.ui.platform.ComposeView{cad8567 V.E...... ......I. 0,0-0,0}
at androidx.compose.ui.internal.InlineClassHelperKt.throwIllegalStateExceptionForNullCheck(InlineClassHelper.kt:32)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:455)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:321)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion.LifecycleAware$lambda$0(WindowRecomposer.android.kt:165)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion.$r8$lambda$FWAPLXs0qWMqekhMr83xkKattCY(Unknown Source:0)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$$ExternalSyntheticLambda0.createRecomposer(D8$$SyntheticClass:0)
at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:217)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:297)
at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:243)
at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:250)
at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:280)
at android.view.View.dispatchAttachedToWindow(View.java:23105)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3520)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3618)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3077)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10644)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1570)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1579)
at android.view.Choreographer.doCallbacks(Choreographer.java:1179)
at android.view.Choreographer.doFrame(Choreographer.java:1108)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1553)
at android.os.Handler.handleCallback(Handler.java:995)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:248)
at android.os.Looper.loop(Looper.java:338)
at android.app.ActivityThread.main(ActivityThread.java:9067)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)
I searched for solutions on this site and found this question. I tried all the solutions in that question, but i got an error:
Cannot access 'fun performRestore(savedState: Bundle?): Unit': it is internal in 'androidx/savedstate/SavedStateRegistry'.
Here's my current code:
package com.example
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
class OverlayLifecycle : LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {
//Lifecylce Methods
override val lifecycle get() = lifecycleRegistry
override val viewModelStore get() = store
private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
private fun handleLifecycleEvent(event: Lifecycle.Event) =
lifecycleRegistry.handleLifecycleEvent(event)
override fun onCreate() {
super.onCreate()
savedStateRegistry.performRestore(null)
handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
}
override fun onDestroy() {
super.onDestroy()
handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
//ViewModelStore Methods
private val store = ViewModelStore()
//SaveStateRegestry Methods
override val savedStateRegistry get() = SavedStateRegistryController.create(this).savedStateRegistry
}
Also i don't know how to implement this properly inside a random function in the application. For example:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// set the layout parameters of the window
val params = WindowManager.LayoutParams( // Shrink the window to wrap the content rather
// than filling the screen
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT, // Display it on top of other application windows
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // Don't let it grab the input focus
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, // Make the underlying application window visible
// through any transparent parts
PixelFormat.TRANSLUCENT
)
val view = ComposeView {
Text("gherdiguvofwfehgoesg")
}
// Define the position of the
// window within the screen
params.gravity = Gravity.CENTER
val windowManager = context.getSystemService(WINDOW_SERVICE) as WindowManager
runOrLog("Applocker") {
// check if the view is already
// inflated or present in the window
if (view.windowToken == null && view.parent == null) {
windowManager.addView(view, params);
}
}
}
I need some help with implementing the lifecycle owner class.
Use the following code:
val view = ComposeView(this).apply {
setContent {
// content
}
// Trick The ComposeView into thinking we are tracking lifecycle
val lifecycleOwner = ComposeLifecycleOwner()
lifecycleOwner.performRestore(null)
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
setViewTreeLifecycleOwner(lifecycleOwner)
setViewTreeSavedStateRegistryOwner(lifecycleOwner)
}
ComposeLifecycleOwner:
import android.os.Bundle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleRegistry
import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
class ComposeLifecycleOwner : SavedStateRegistryOwner {
private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
private var mSavedStateRegistryController: SavedStateRegistryController = SavedStateRegistryController.create(this)
/**
* @return True if the Lifecycle has been initialized.
*/
val isInitialized: Boolean
get() = true
override val lifecycle = mLifecycleRegistry
fun setCurrentState(state: Lifecycle.State) {
mLifecycleRegistry.currentState = state
}
fun handleLifecycleEvent(event: Lifecycle.Event) {
mLifecycleRegistry.handleLifecycleEvent(event)
}
override val savedStateRegistry: SavedStateRegistry
get() = mSavedStateRegistryController.savedStateRegistry
fun performRestore(savedState: Bundle?) {
mSavedStateRegistryController.performRestore(savedState)
}
fun performSave(outBundle: Bundle) {
mSavedStateRegistryController.performSave(outBundle)
}
}
Source: https://gist.github.com/handstandsam/6ecff2f39da72c0b38c07aa80bbb5a2f
Thanks to @CommonsWare for giving me the idea!