You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在OverlayPlugin中使用Jetpack Compose定制导航栏遇上下文错误

解决SystemUI OverlayPlugin集成Jetpack Compose时的ViewConfiguration非UI上下文错误

问题背景

我正在尝试使用Jetpack Compose定制SystemUI导航栏,这类场景无法像普通应用那样直接使用Activity或Fragment,必须通过实现OverlayPlugin接口来完成,同时在AndroidManifest.xml中声明对应的Service,代码如下:

<service android:name=".SampleOverlayPlugin"
    android:label="@string/plugin_label"
    android:exported="false">
<intent-filter>
    <action android:name="com.android.systemui.action.PLUGIN_OVERLAY" />
</intent-filter>
</service>

遇到的错误

在使用提供的上下文初始化Compose相关组件时,触发了以下异常:

Tried to access the API:ViewConfiguration which needs to have proper configuration from a non-UI
Context:com.android.documentsui.DocumentsApplication@608ad35 The API:ViewConfiguration needs a proper configuration. Use UI contexts such as an activity or a context created via createWindowContext(Display, int, Bundle) or createConfigurationContext(Configuration) with a proper configuration.
java.lang.IllegalAccessException: Tried to access the API:ViewConfiguration which needs to have proper configuration from a non-UI Context:com.android.documentsui.DocumentsApplication@608ad35

已尝试但无效的方案

  • 针对InputMethodService中ComposeView无法传递ViewTreeLifecycleOwner的修复方案
  • Android Service中集成Jetpack Compose的通用适配方案

解决方案

这个错误的核心是使用了非UI上下文访问需要配置信息的View相关API,需要为Compose创建符合要求的UI上下文:

  1. 创建带正确配置的UI上下文
    在OverlayPlugin的实现类中,不要直接使用传入的Application上下文,而是通过createWindowContext创建关联当前显示设备的UI上下文,并指定符合SystemUI overlay要求的窗口类型:
// 获取当前Display,也可以根据SystemUI提供的Display信息调整
val display = context.display ?: Display.DEFAULT_DISPLAY
// 创建UI上下文,窗口类型根据导航栏场景选择,比如TYPE_SYSTEM_UI_OVERLAY或TYPE_NAVIGATION_BAR_PANEL
val windowContext = context.createWindowContext(
    display,
    WindowManager.LayoutParams.TYPE_SYSTEM_UI_OVERLAY,
    null
)
  1. 使用UI上下文初始化ComposeView
    创建ComposeView时传入上述创建的windowContext,而非原始上下文:
val composeView = ComposeView(windowContext)
  1. 手动关联LifecycleOwner
    由于插件运行在非Activity环境,需要手动为ComposeView设置ViewTreeLifecycleOwner,推荐使用ProcessLifecycleOwner来关联应用进程的生命周期:
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.compose.ui.platform.ViewTreeLifecycleOwner

composeView.apply {
    ViewTreeLifecycleOwner.set(this, ProcessLifecycleOwner.get())
    setContent {
        // 这里编写你的导航栏Compose UI代码
        // 例如:NavigationBarUI()
    }
}
  1. 正确挂载到SystemUI Overlay
    将配置好的ComposeView添加到SystemUI提供的Overlay容器时,确保使用符合要求的LayoutParams,比如设置合适的宽度、高度、对齐方式,以及对应的窗口flags。

同时要注意在OverlayPlugin的生命周期回调(如onAttach、onDetach)中,正确管理ComposeView的挂载与销毁,避免内存泄漏。

内容的提问来源于stack exchange,提问作者220284

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:17:28