6

Every few days I get a crash report for my application with the following stack trace, or small variants thereof (with different line numbers based on different android versions)

java.lang.NullPointerException at
WebView.java:8241:in `android.webkit.WebView$PrivateHandler.handleMessage'
Handler.java:99:in `android.os.Handler.dispatchMessage'
Looper.java:150:in `android.os.Looper.loop'
ActivityThread.java:4293:in `android.app.ActivityThread.main'
Method.java:-2:in `java.lang.reflect.Method.invokeNative'
Method.java:507:in `java.lang.reflect.Method.invoke'
ZygoteInit.java:849:in `com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run'
ZygoteInit.java:607:in `com.android.internal.os.ZygoteInit.main'
NativeStart.java:-2:in `dalvik.system.NativeStart.main'

This specific stack was on Android 2.3.4 on a HTC EVO 3D PG86100 device. My app does host several webviews for some oAuth-related login scenarios.

How should I go about trying to figure out how to fix this? I've tried looking on grepcode to find the source, but I'm unable to find a matching line number that makes sense. Is my Grepcode-fu weak?

PacificSky
  • 3,422
  • 2
  • 25
  • 24
  • Any pattern to the Android releases or device manufacturers? – CommonsWare Sep 07 '12 at 23:45
  • Interesting observation! It seems to be confined to HTC devices! – PacificSky Sep 09 '12 at 15:30
  • I've added the HTC tag, as there's a chance that you'll get some HTC assistance. I assume that you do not have a reproducible test case -- correct? – CommonsWare Sep 09 '12 at 15:35
  • Correct. I've tried various things but I haven't been able to repro this. All of these have been from the wild. – PacificSky Sep 09 '12 at 17:51
  • I submitted a bug to HTC's internal bug tracker. If you have any cases where it happens on newer ROMs, though, that would help. My Sprint Evo 3D upgraded OTA to ICS, for example. So Android 2.3.4 isn't even the current version for a phone that old. Re workarounds, maybe try to only have one WebView, they all share things like threads in the background and multiple can cause trouble. I've seen people with a new Activity and WebView for each page someone browses when they could just load the page in the same one. Remove listeners, remove WebView from the parent view, and call destroy when done. – Lance Nanek Sep 17 '12 at 15:15
  • I have similar crash reports from the HTC Evo 3D, HTC Design 4G and HTC OneX running anything from 4.0.4 to 4.1.1. The stack is the same, though line numbers differ. On the Evo 3D on 4.0.4, for example, it happens at WebView.java:9710:in `android.webkit.WebView$PrivateHandler.handleMessage' – PacificSky Sep 17 '12 at 17:34

1 Answers1

5

I ran into this issue recently and in my case I managed to figure out that a secondary bug fix was causing this issue.

So, if you didn't create a custom class which extends webview, that overrides onCheckIsTextEditor to always return true because of a suggestion in this android bug report... I would stop reading here.

If you have done that, then it appears that this fix has already been implemented by HTC and for some reason causes it to crash when it receives focus. This issue manifested itself in two places for me, when placing touch events on the view and by setting the views visibility. In my project I set a WebViewClient and waited until the page had finished loading before setting the webview's visibility to visible. This caused the following stack trace:

java.lang.NullPointerException at android.webkit.WebView.navHandledKey(WebView.java:9353)
    at android.webkit.WebView.requestFocus(WebView.java:7910)
    at android.view.View.requestFocus(View.java:3718)
    at android.view.View.requestFocus(View.java:3696)
    at android.view.ViewRoot.focusableViewAvailable(ViewRoot.java:1803)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:474)
    at android.view.View.setFlags(View.java:4680)
    at android.view.View.setVisibility(View.java:3163)

By wrapping the setVisibility call in a try/catch I was able to determine if I should override the touch events or not. If I caught the event, that would mean I should disable the override. This is an example of what I did:

try {
    webView.setVisibility(View.VISIBLE);
} catch (NullPointerException e) {
    Log.i(TAG, "Error setting webview visibility due to overriding focus. It will be disabled.");
    webView.setOverrideOnCheckIsTextEditor(false);
    // Confirm window is visible
    webView.setVisibility(View.VISIBLE);
}

My custom webview now looks like this, special attention paid to the final two methods:

/**
 * When using a webview in a dialog, there are issues relating to the keyboard not appearing when focusing on a text box.
 * This overrides a function to ensure the keyboard is shown when focusing on a text box in a webview.
 * See link for bug report and solution.
 *
 * @see http://code.google.com/p/android/issues/detail?id=7189
 * @see http://stackoverflow.com/questions/12325720
 * @author James O'Brien
 * @since 10/16/2012
 */
public class FocusableWebView extends WebView {

    private boolean mOverrideCheckIsTextEditor = true;

    /**
     * Default Constructor
     *
     * @param context
     */
    public FocusableWebView(Context context) {
        super(context);
    }

    /**
     * Default Constructor
     *
     * @param context
     * @param attrs
     */
    public FocusableWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Default Constructor
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    public FocusableWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onCheckIsTextEditor() {
        if (mOverrideCheckIsTextEditor) {
            return true;
        } else {
            return super.onCheckIsTextEditor();
        }
    }

    /**
     * Enable/Disable overriding of onCheckIsTextEditor to always return true.
     */
    public void setOverrideOnCheckIsTextEditor(boolean foo) {
        mOverrideCheckIsTextEditor = foo;
    }
}

Sorry I can't go into more detail about why this fixes the issue. All I can assume is that its related to focus and dynamically disabling it works a treat :)

** Update (12/11/12) **

Managed to solve both issues presented above. It seemed to be an issue with the focus of the webview. My code now looks like this

webView.setVisibility(View.VISIBLE);
webView.setFocusable(true);
webView.requestFocus();

I would suggest making sure that you explicitly set the focusable attribute to 'true' or calling setFocusable(true).

jimmithy
  • 6,360
  • 2
  • 31
  • 29
  • I think your fix is for a slightly different issue than the original question. I have seen the crash you're seeing (in navHandledKey), so I think your fix might fix that crash. However, I'm not sure it fixes the original stack trace I posted (crash in PrivateHandler.handleMessage). Can you confirm you've seen that crash in your app and it has gone away after your fix? – PacificSky Oct 17 '12 at 21:40
  • I had an identical stack trace on similar HTC versioned phones and I discovered that turning off the focus override solved the issue. I understand, and noted in the second paragraph, that my fix is rather specific, but I hope pointing out that it was related to the webview gaining focus will be of some help. – jimmithy Oct 17 '12 at 22:58
  • Thanks. I've implemented your fix. If I don't see the same crashes again I'll mark it as the answer! – PacificSky Oct 19 '12 at 23:44
  • I managed to get my hands on a HTC device and I can repro this consistently, 100% of the time. The fix above doesn't work for me, sorry :( – PacificSky Nov 03 '12 at 02:05
  • I just updated my answer with a discovery I made today after ending up with an identical stack trace to yourself. Hope this works for you. – jimmithy Dec 11 '12 at 17:13