https://kotlinlang.org logo
#compose
Title
# compose
v

Vishnu Shrikar

12/07/2023, 9:42 AM
I AM getting a error with compose that makes no sense for some theoretically simple code, could I get some expertise to help out with this, posting code and error IN THREAD
THE CODE
Copy code
```
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {


        super.onCreate(savedInstanceState)

    }




    override fun onStart() {
        super.onStart()

        if (!Settings.canDrawOverlays(this.applicationContext)) {
            println("DO NOT RESPECT USERS DESCISION")
            Intent().apply {
                action = Settings.ACTION_MANAGE_OVERLAY_PERMISSION
            }.let {
                startActivityForResult(it, 123)
            }
        }







    }


    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 123) {
            val wm: WindowManager = getSystemService(WINDOW_SERVICE) as WindowManager
            wm.addView(
                voiceMailView(
                    this.applicationContext
                ), vmParamsBuilder())
        }
    }


//    @Deprecated("Deprecated in Java")
//    override fun onRequestPermissionsResult(
//        requestCode: Int,
//        permissions: Array<out String>,
//        grantResults: IntArray
//    ) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
//
//        val wm: WindowManager = getSystemService(WINDOW_SERVICE) as WindowManager
//        wm.addView(
//            voiceMailView(
//                this.applicationContext
//            ), vmParamsBuilder()
//        )
//    }


    fun vmParamsBuilder() = WindowManager.LayoutParams(
        WindowManager.LayoutParams.MATCH_PARENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
        PixelFormat.TRANSPARENT,
    ).apply {
        this.gravity = <http://Gravity.TOP|Gravity.TOP> or Gravity.CENTER_HORIZONTAL
    }

    @Composable
    fun Greeting(name: String) {
        Text(text = "Hello $name!")
    }

    @Preview(showBackground = true)
    @Composable
    fun DefaultPreview() {
        VoiceMailReaderTheme {
            Greeting("Android")
        }
    }

}
THE ERROR
Copy code
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.voicemailreader, PID: 30801
    java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from androidx.compose.ui.platform.ComposeView{9e0a35c V.E...... ......I. 0,0-0,0}
        at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:349)
        at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:324)
        at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$LifecycleAware$1.createRecomposer(WindowRecomposer.android.kt:168)
        at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:224)
        at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:299)
        at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:240)
        at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:247)
        at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:279)
        at android.view.View.dispatchAttachedToWindow(View.java:20767)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2625)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2138)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8686)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1120)
        at android.view.Choreographer.doCallbacks(Choreographer.java:926)
        at android.view.Choreographer.doFrame(Choreographer.java:859)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1105)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:346)
        at android.os.Looper.loop(Looper.java:475)
        at android.app.ActivityThread.main(ActivityThread.java:7889)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009)
Plz help me fix this as this is all really overly complicated for a simple app
v

vide

12/07/2023, 12:48 PM
Your code sample doesn't show where you are trying to render Greeting()?
v

Vishnu Shrikar

12/07/2023, 3:39 PM
Oh whoops did not show the view code. I dont render the greeting anywhere. I have a setcontent inside of voiceMailView which is just I think a box. I can post code a bit later.
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 4:02 PM
ComposeView requires something in its view tree to provide a LifecycleOwner (and also SavedStateRegistry). It does this via the androidx ViewTree* helpers. When you use ComponentActivity, it sets up the view tree with those things for you automatically. Also, when you use the Popup and Dialog composables then you get that automatically as well. However, you’re adding your compose view to a new root view via WindowManager.addView. That is a completely separate view tree, so you have to provide the dependencies yourself. You can take a look at the PopupLayout class in compose for an example of how to do that.
v

Vishnu Shrikar

12/07/2023, 4:20 PM
Ok ill do that thanks. I would use an activity but i need a view as im making an overlay
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 5:37 PM
Yep that makes sense. If you’re doing the overlay from compose itself I would use Popup, but if you’re doing it directly from the activity or a non-compose view this is the way to go
v

Vishnu Shrikar

12/07/2023, 5:38 PM
I Wanted to use system error but that did not work so im using the application overlay. I dont know why system error failed to work but my HOPE is that application overlay is transparent enough
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 5:40 PM
Window type doesn’t affect transparency afaik, it mainly affects layering? But I am guessing the system error type didn’t work because it’s only meant for system apps?
v

Vishnu Shrikar

12/07/2023, 5:41 PM
GOD DAMN IT, its a signature level perm? Oh sorry by transparency I mean touch transparency. I want to be able to click the overlay and the non overlay
I really hope i wont have to make a magisk module for this
n

navczydev

12/07/2023, 6:30 PM
I had same issue a coupe of weeks ago and fixed it by setting the owners. window?.decorView?.setViewTreeLifecycleOwner(sideSheetDialog) window?.decorView?.setViewTreeSavedStateRegistryOwner(sideSheetDialog) window?.decorView?.setViewTreeOnBackPressedDispatcherOwner(sideSheetDialog)
v

Vishnu Shrikar

12/07/2023, 6:31 PM
what is a window in your case? is that just your view? or is it a global variable
n

navczydev

12/07/2023, 6:32 PM
In my case its in activity, I have integrated the Sidesheet from material
Its Sidesheet's window
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:33 PM
If you’re creating a top level window yourself by calling addView, you can just set the owners directly on your view
☝️ 1
v

Vishnu Shrikar

12/07/2023, 6:33 PM
My goal is to create the view and then yeet the activity
Ok so i just need to figure out how to get the lifecycle owner objects
n

navczydev

12/07/2023, 6:35 PM
Here is full code, back then we need to set owners it wasn't set for us with(sideSheetDialog) { window?.decorView?.setViewTreeLifecycleOwner(sideSheetDialog) window?.decorView?.setViewTreeSavedStateRegistryOwner(sideSheetDialog) window?.decorView?.setViewTreeOnBackPressedDispatcherOwner(sideSheetDialog) setContentView(sideSheetContentBinding.root) }
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:35 PM
You can just pull them out of the activity/context/view that owns the compose view
v

Vishnu Shrikar

12/07/2023, 6:35 PM
I see that makes sense, but if i were to say finish the activity that uses the view, would that view get yeeted too?
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:41 PM
Yea, if your window is gonna live on its own then you need your own support lifecycle & state registry, at least
v

Vishnu Shrikar

12/07/2023, 6:42 PM
can i not get one from root? (or globalscope or something tied directly to application)
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:42 PM
Root what
v

Vishnu Shrikar

12/07/2023, 6:42 PM
idk its a keyword
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:42 PM
Most of those things are tied to activity on Android
In general, if you don’t have some kind of component actively registered with the system (eg activity, service, etc) the system can kill your process, so you’re not gonna be able to do anything reliably. If you have something to anchor to, then worst case you can create your own lifecycle and state registry and manage them yourself for your compose view. But it’s more work, and sounds like you might be trying to fight with the system instead of work with it
v

Vishnu Shrikar

12/07/2023, 6:47 PM
oh im 100% trying to fight the system, the goal of this is going to be to overlay on the telephone app
It looks like you can make activities that simply dont do anything except live though so that would work, like no display etc... How did facebook do it with chatheads?
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:50 PM
AFAIK used to be hacks, but now there’s an API for that: https://developer.android.com/develop/ui/views/notifications/bubbles
v

Vishnu Shrikar

12/07/2023, 6:51 PM
why would they make an api like this, its so specific and not extensible. Bad design unless you specifically are trying to work against the dev. What were the hacks?
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:52 PM
why would they make an api like this, its so specific and not extensible
¯\_(ツ)_/¯ lol
v

Vishnu Shrikar

12/07/2023, 6:52 PM
would it be better to just tie this to a service?
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 6:52 PM
i don’t know the specifics of how facebook did it, i’m sure there were articles or talks and stuff about how to do that sort of thing before the official API came out
v

Vishnu Shrikar

12/07/2023, 6:53 PM
alright well if i can launch an activity without it coming to the foreground that may work as well then I can just have it there
2 Views