s

    Socheat KHAUV

    1 year ago
    I tried to make a floating window with androidx.compose.ui.platform.ComposeView
    class FloatingService : Service() {
        
        private var windowManager: WindowManager? = null
        override fun onCreate() {
            super.onCreate()
            windowManager = ContextCompat.getSystemService(this, WindowManager::class.java)
            var view = LayoutInflater.from(this).inflate(R.layout.player_popup_close_overlay, null, false)
            val closeOverlayLayoutParams = buildCloseOverlayLayoutParams()
            var composeView = view.findViewById<ComposeView>(R.id.compose_view)
            composeView.setContent {
                Button(onClick = { }) {
                    Text(text = "Click Me")
                }
            }
            Objects.requireNonNull(windowManager)?.addView(view, closeOverlayLayoutParams)
        }
    
    }
    after start service, the app will crash, and there is no error log in the LogCat. if update my view xml (player_popup_close_overlay.xml) by remove ComposeView, and add TextView for testing, it works fine. I am not sure what went wrong with ComposeView
    Adam Powell

    Adam Powell

    1 year ago
    There's definitely an error log in there 🙂 and chances are it's looking for a
    ViewTreeLifecycleOwner
    set on the root view of the new window you're creating
    (please try to keep the code snippets >4-6 lines in the thread so that it doesn't flood the channel!)
    s

    Socheat KHAUV

    1 year ago
    I can see the error log now. 2021-04-29 04:38:46.735 10025-10025/com.example.screenoverlay E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.screenoverlay, PID: 10025 java.lang.IllegalStateException: ViewTreeLifecycleOwner not set for this ComposeView. If you are adding this ComposeView to an AppCompatActivity, make sure you are using AppCompat version 1.3+. If you are adding this ComposeView to a Fragment, make sure you are using Fragment version 1.3+. For other cases, manually set owners on this view by using
    ViewTreeLifecycleOwner.set()
    and
    ViewTreeSavedStateRegistryOwner.set()
    . at androidx.compose.ui.platform.AbstractComposeView.checkViewTreeOwners(ComposeView.android.kt:179) at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:195) at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:235) at android.view.View.dispatchAttachedToWindow(View.java:20479) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2417) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972) at android.view.Choreographer.doCallbacks(Choreographer.java:796) at android.view.Choreographer.doFrame(Choreographer.java:731) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
    Adam Powell

    Adam Powell

    1 year ago
    yep, use
    ViewTreeLifecycleOwner.set
    on the root view of that window (the one you add to the window manager) to set a LifecycleOwner for the ComposeView to locate and use
    you'll likely want to use a
    LifecycleRegistry
    instance as your implementation of the
    Lifecycle
    object returned by it, and you should drive its lifecycle events as appropriate for your service to emulate an activity lifecycle
    s

    Socheat KHAUV

    1 year ago
    It works now and shows my composable able button now. but somehow, my composable button is not clickable.
    composeView.setContent {
        Button(onClick = { Log.d("test","from overlay window")}) {
            Text(text = "Click Me 1")
        }
    }
    @Adam Powell, all good now. actually I gave window param incorrectly, the overlay window does not response to any touch event. We need to use below line to root view.
    ViewTreeLifecycleOwner.set(view, owner)
    ViewTreeSavedStateRegistryOwner.set(view, owner)
    I also need to give a service binder and service connection, so that I could add an activity reference (life cycle owner) back to my service class. Thanks you for helping.
    I added a button into my composable overlay view. after click, it should open main activity immediately, but it wasn’t, there was a several second delay, look like click event got blocking some where. I am not sure what went wrong. do you have any idea ? I am also here by to share my project code. just incase if want to look.
    Adam Powell

    Adam Powell

    1 year ago
    without looking at the code, nothing springs to mind. If you can narrow down the issue enough to post as a snippet in a thread here it might be easier for folks here to take a look.
    s

    Socheat KHAUV

    1 year ago
    Inside - OverlayWindowScreen.kt
    var composeView = overlayView!!.findViewById<ComposeView>(R.id.compose_view)
    composeView.setContent {
        SmallWindowScreen()
    }
    SmallWindowScreen it is a composeable function which use for display overlay window there is a button “Open”, click on that button will open MainActivity
    var intent = Intent(context, MainActivity::class.java)
    context.startActivity(intent)
    and the problem is that, if we click that button to many time, that button would freeze, and we click only one and wait, it will open activity some later (mabye 10seconds)
    Adam Powell

    Adam Powell

    1 year ago
    try using https://ui.perfetto.dev to see where the time is going after the button click