不支持的操作异常:尝试从未与显示相关联的上下文中获取显示。

15

我的应用程序出现了UnsupportedOperationException崩溃。所有的崩溃都与Moto Android 11设备有关。可以看到它与onKeyUp有些相关。但是仍然不知道如何复制或修复它。非常感谢任何帮助。

Fatal Exception: java.lang.UnsupportedOperationException: Tried to obtain display from a Context not associated with  one. Only visual Contexts (such as Activity or one created with Context#createWindowContext) or ones created with Context#createDisplayContext are associated with displays. Other types of Contexts are typically related to background entities and may return an arbitrary display.
   at android.app.ContextImpl.getDisplay(ContextImpl.java:2580)
   at android.content.ContextWrapper.getDisplay(ContextWrapper.java:1030)
   at android.content.ContextWrapper.getDisplay(ContextWrapper.java:1030)
   at android.app.Activity.onKeyUp(Activity.java:3859)
   at android.view.KeyEvent.dispatch(KeyEvent.java:2866)
   at android.app.Activity.dispatchKeyEvent(Activity.java:4176)
   at androidx.core.app.ComponentActivity.superDispatchKeyEvent(ComponentActivity.java:122)
   at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:84)
   at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:140)
   at androidx.appcompat.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:558)
   at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
   at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2814)
   at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
   at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:418)
   at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:6101)
   at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5969)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5464)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5521)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5487)
   at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5639)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5495)
   at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5696)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5468)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5521)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5487)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5495)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5468)
   at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8313)
   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8229)
   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8190)
   at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:5219)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loop(Looper.java:250)
   at android.app.ActivityThread.main(ActivityThread.java:7766)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)

1
你能够确定是哪个Context被调用了getDisplay()吗? - msbit
@msbit在日志中的getDisplay()是一个系统调用,而不是来自应用程序。据我所知,onKeyUp是触发问题的原因。onKeyUp是键盘导航按钮。 - Shahal
是的,从日志上看很有道理,但如果您无法确定正在调用哪个“Context”或“Activity”,那么您将无法取得太大进展。 - msbit
经过一番搜索,我找到了一个不同应用程序的线程,他们也在Android 11上遇到了这个问题,也许你可以创建一个带有Android 11的模拟器,看看是否能够在那里重现错误? - Dan Baruch
1
@Shahal 我也遇到了同样的问题,我需要检查一下你是否正在使用自定义的AppCompatDelegate,就像这个 https://dev59.com/HFMI5IYBdhLWcg3w0e97 - Jemo Mgebrishvili
显示剩余2条评论
3个回答

3

确保在您覆盖活动内的attachBaseContext时,不要设置与显示不相关的基本上下文,例如应用程序或服务上下文等非视觉环境都是不可行的。否则,在按键/键盘上某些特定键时,会导致摩托罗拉设备的大部分崩溃。在我的情况下是G30、G60和G60s,请注意某些摩托罗拉设备不受影响。

因此,在您的活动中覆盖attachBaseContext()时,请确保在someMethodThatReturnsNewBaseContext()方法中实际返回正确的上下文。

override fun attachBaseContext(newBase: Context) {
    val newBaseContext = someMethodThatReturnsNewBaseContext(newBase)
    super.attachBaseContext(newBaseContext)
}

我发现在我的someMethodThatReturnsNewBaseContext()实现中,我返回了context.applicationContext.createConfigurationContext(),一旦我直接返回context.createConfigurationContext(),问题就在Motorola设备上得到解决。

只有(大多数?)来自活动的上下文与显示相关联,因为Activity实际上继承自ContextThemeWrapper,而其他上下文组件(如Application和Service)仅继承ContextWrapper,因此它们被认为是“非可视化”的。

如果您在覆盖attachBaseContext()时没有做任何花哨的事情,请查看您的代码库中任何传递或调用非活动上下文方法的地方,您会找到罪魁祸首。


0
我也遇到了这个问题,异常是由以下源代码引起的。
public Display getDisplay() {
    if (!isAssociatedWithDisplay()) {
        throw new UnsupportedOperationException("Tried to obtain display from a Context not "
            + "associated with one. Only visual Contexts (such as Activity or one created "
            + "with Context#createWindowContext) or ones created with "
            + "Context#createDisplayContext are associated with displays. Other types of "
            + "Contexts are typically related to background entities and may return an "
            + "arbitrary display.");
    }
    return getDisplayNoVerify();
}

异常是由于重写了attachBaseContext方法并重新创建了content对象。有必要检查生成方法是否合理。

0

作为一种解决方法,您可以覆盖onKeyUponKeyDown(不幸的是,我无法看到您的完整堆栈跟踪,因此我不知道您需要覆盖哪个方法),并在其中返回true/false。

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        return false
    }
    
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return false
    }


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。- 来自审查 - markspace
我有同样的问题,这是完整的堆栈跟踪 :) - ghita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接