如何根据需要安全地打开和关闭 WebView 缩放

发布于 2024-10-21 12:28:11 字数 2716 浏览 2 评论 0 原文

正如这个未回答的问题中提到的: WebView 抛出接收器未注册:android.widget .ZoomButtonsController

通过根据需要打开和关闭 WebView 缩放控件会引发以下情况:

java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController

对于某些用户。我本人没有见过这种崩溃,但我在来自野外设备的日志中看到过它。它不会经常发生,但无论如何它都是崩溃的。有什么想法吗?

谢谢

更新:如何重现

我找到了如何重现此崩溃:http://code.google.com/p/android/issues/detail?id=15694

如果我发现解决方法,我会报告。


根据要求,完整的堆栈跟踪:

java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController$1@487a4290
at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:793)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:913)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:404)
at android.widget.ZoomButtonsController$2.handleMessage(ZoomButtonsController.java:178)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

和另一个类似的:

java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:391)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:236)
at android.view.Window$LocalWindowManager.removeView(Window.java:432)
at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:406)
at android.widget.ZoomButtonsController$2.handleMessage(ZoomButtonsController.java:178)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

As mentioned in this unanswered question: WebView throws Receiver not registered: android.widget.ZoomButtonsController

By turning the WebView zoom controls on and off as needed throws this:

java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController

For some users. I myself have not seen this crash, but I have seen it in the logs coming from devices in the wild. It doesn't happen super frequently, but it is a crash regardless. Any ideas?

Thanks

Update: How to reproduce

I found how to reproduce this crash: http://code.google.com/p/android/issues/detail?id=15694

I'll report back if I discover a workaround.


As requested, the full stack trace:

java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController$1@487a4290
at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:793)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:913)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:404)
at android.widget.ZoomButtonsController$2.handleMessage(ZoomButtonsController.java:178)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

and another similar one:

java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:391)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:236)
at android.view.Window$LocalWindowManager.removeView(Window.java:432)
at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:406)
at android.widget.ZoomButtonsController$2.handleMessage(ZoomButtonsController.java:178)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

夜巴黎 2024-10-28 12:28:11

在 Zoom 上,我发现如果在调用 WebView.destroy() 之前等待缩放控件淡出,则不再发生崩溃。因此,我覆盖了 WebView.destroy() 以将消息发布到处理程序以在几秒钟后调用 WebView.destroy() 。从WebView源码中我们会看到淡出间隔是:

// The time that the Zoom Controls are visible before fading away
private static final long ZOOM_CONTROLS_TIMEOUT =
        ViewConfiguration.getZoomControlsTimeout();

所以我使用ViewConfiguration.getZoomControlsTimeout() + 1000L作为调用WebView的destroy方法之前的延迟。到目前为止还没有发生崩溃。

On a Zoom, I found that if one waits for the zoom control to fade out before calling WebView.destroy() a crash no longer occurs. So I've overwritten WebView.destroy() to post a message to a Handler to call WebView.destroy() after a few seconds. From the WebView source we will see the fade-out interval is:

// The time that the Zoom Controls are visible before fading away
private static final long ZOOM_CONTROLS_TIMEOUT =
        ViewConfiguration.getZoomControlsTimeout();

So I used ViewConfiguration.getZoomControlsTimeout() + 1000L as the delay before calling WebView's destroy method. So far no crashes.

放飞的风筝 2024-10-28 12:28:11

如果您只想让捏缩放与您的 Web 视图一起使用,并且您可以在没有缩放按钮的情况下生活,您可以对您的 Web 视图执行此操作:

webView.getSettings().setBuiltInZoomControls(true); // will give pinch zoom
webView.getSettings().setDisplayZoomControls(false); // but won't display the zoom buttons

添加

webView.getSettings().setBuiltInZoomControls(true);

onDestroy / onDestroyView 在 3.x 上没有帮助。

If you only want to have pinch zoom working with your webview and you can live without the zoom buttons, you can do this to your webview:

webView.getSettings().setBuiltInZoomControls(true); // will give pinch zoom
webView.getSettings().setDisplayZoomControls(false); // but won't display the zoom buttons

adding

webView.getSettings().setBuiltInZoomControls(true);

in onDestroy / onDestroyView did not help on 3.x.

深陷 2024-10-28 12:28:11

webView.getSettings().setBuiltInZoomControls(true);不适合我。

然而,dkneller 的建议确实有效:

    long timeout = ViewConfiguration.getZoomControlsTimeout();
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            webview.destroy();
        }
    }, timeout);

webView.getSettings().setBuiltInZoomControls(true); did not work for me.

dkneller's suggestion did work, however:

    long timeout = ViewConfiguration.getZoomControlsTimeout();
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            webview.destroy();
        }
    }, timeout);
就是爱搞怪 2024-10-28 12:28:11

将这一行放入 onDestroy 对我有用:

webView.setVisibility(View.GONE);

Put this line in onDestroy works for me:

webView.setVisibility(View.GONE);

旧梦荧光笔 2024-10-28 12:28:11

这个解决方案工作正常,你只需要在销毁它之前从布局中删除 webview:

@Override
    public void onDestroy() {
        if (webView!=null && webView.getParent()!=null){
            ((ViewGroup)webView.getParent()).removeView(webView);
            webView.destroy();
            webView=null;
        }
        super.onDestroy();
    }

没有处理程序,没有延迟,我认为这是最好的解决方案

This solution works fine, you simply need to remove the webview from the layout before destroying it:

@Override
    public void onDestroy() {
        if (webView!=null && webView.getParent()!=null){
            ((ViewGroup)webView.getParent()).removeView(webView);
            webView.destroy();
            webView=null;
        }
        super.onDestroy();
    }

No handlers, no delays, i think it's the best solution

过度放纵 2024-10-28 12:28:11

如果您偶然发现这个问题,请务必先检查错误报告以查看来自 Google 的状态,但除此之外,这里有一个迄今为止对我来说非常有效的解决方法:

将此行添加到您的 onDestory() 方法中:

webView.getSettings().setBuiltInZoomControls(true);

If you are stumbling upon this question, be sure to check the bug report first to see what the status is from Google, but otherwise here is a workaround that is working so far so good for me:

Add this line to your onDestory() method:

webView.getSettings().setBuiltInZoomControls(true);
泼猴你往哪里跑 2024-10-28 12:28:11

我在这里有同样的问题:现有的应用程序吹升级到android 3.0 XOOM。 ZoomButtonsController 泄漏?

当调用 registerReceiver 之前发生异常,然后您稍后尝试取消注册 Receiver 而未注册它时,就会发生这种情况。

这可能是android 3.0的一个bug。

I have the same issue here: Existent app blowing up with android 3.0 XOOM. ZoomButtonsController Leak?

This happens when there's an exception that happens before registerReceiver is called and then you try to unregisterReceiver later without it ever been registered.

It's probably a android 3.0 bug.

我还不会笑 2024-10-28 12:28:11

java.lang.IllegalArgumentException:视图未附加到窗口管理器异常通常发生在存在对话框(即进度对话框)并且您在活动关闭时将其关闭时。您能否判断您的 Activity 中是否确实有进度对话框,以便我可以继续分析? 还发布您的活动的代码片段,这可能有助于我们确定您的应用程序崩溃的原因...

此外,您还说您不会经常遇到应用程序崩溃,因此请进行测试以证实我的怀疑。当您的应用程序运行时,更改屏幕方向,并在几分钟后执行几次,最好是在执行某些工作时涉及进度对话框。它可能会使应用程序崩溃,这应该告诉我们错误是因为进度对话框没有正确关闭。

我的理论:当你切换方向时,Android 将创建一个新的视图。您可能会崩溃,因为您的后台线程正在尝试更改旧线程的状态。 (它也可能遇到问题,因为您的后台线程不在 UI 线程上)

java.lang.IllegalArgumentException: View not attached to window manager exception mostly occurs when there is a dialog (i.e. Progress Dialog) and you are dismissing it when the Activity has closed. Could you tell if your Activity indeed has a Progress Dialog in it , so that I can continue with my analysis ? Also post your Activity's code snippet which might help us identifying why your app is crashing ...

Also you say you don't face application crash often frequently, so do a test to confirm my suspicions. When your application is running change your screen orientation , and do it a couple of times , after few minutes, preferably when there is Progress Dialog involved in doing some work. It might crash the application which should tell us that the error is because the Progress Dialog isn't dismissing correctly.

My Theory : When you switch orientations, Android will create a new View. You're probably getting crashes because your background thread is trying to change the state on the old one. (It may also be having trouble because your background thread isn't on the UI thread)

可遇━不可求 2024-10-28 12:28:11

将其添加到您的活动中:

@Override
  public void finish() {
      ViewGroup view = (ViewGroup) getWindow().getDecorView();
      view.removeAllViews();
      super.finish();
}

Add this to your activity:

@Override
  public void finish() {
      ViewGroup view = (ViewGroup) getWindow().getDecorView();
      view.removeAllViews();
      super.finish();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文