Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely turn WebView zooming on and off as needed

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)
like image 445
cottonBallPaws Avatar asked Mar 11 '11 00:03

cottonBallPaws


People also ask

How do I zoom out in Webview Android?

webview. getSettings(). setLoadWithOverviewMode(true); This will cause the webview to be zoomed out initially.

What is zoom control in Android?

In Android, Zoom Control is a class that has some set of methods that are used to control the zoom functionality. It has two buttons that are used to control the zoom functionality (ie Zoom In and Zoom Out). Zoom Control Class has been deprecated in API Version 29.


3 Answers

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.

like image 54
dkneller Avatar answered Sep 19 '22 20:09

dkneller


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.

like image 30
Stephan Avatar answered Sep 20 '22 20:09

Stephan


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);
like image 26
dvn Avatar answered Sep 23 '22 20:09

dvn