6

每隔几天,我就会收到我的应用程序的崩溃报告,其中包含以下堆栈跟踪或其小型变体(基于不同的 android 版本具有不同的行号)

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'

此特定堆栈位于 HTC EVO 3D PG86100 设备上的 Android 2.3.4 上。我的应用确实为一些与 oAuth 相关的登录场景托管了几个 webview。

我应该如何去尝试弄清楚如何解决这个问题?我尝试在 grepcode 上查找源代码,但找不到有意义的匹配行号。我的 Grepcode-fu 弱吗?

4

1 回答 1

5

我最近遇到了这个问题,在我的情况下,我设法弄清楚是次要错误修复导致了这个问题。

所以,如果你没有创建一个扩展 webview 的自定义类,它会覆盖 onCheckIsTextEditor 以始终返回 true,因为这个android 错误报告中的建议......我会停止阅读这里。

如果您已经这样做了,那么看来此修复程序已由 HTC 实施,并且由于某种原因导致它在收到焦点时崩溃。对我来说,这个问题在两个地方表现出来,在视图上放置触摸事件和设置视图可见性时。在我的项目中,我设置了一个 WebViewClient 并等到页面完成加载,然后再将 webview 的可见性设置为可见。这导致了以下堆栈跟踪:

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)

通过将 setVisibility 调用包装在 try/catch 中,我能够确定是否应该覆盖触摸事件。如果我抓住了这个事件,那意味着我应该禁用覆盖。这是我所做的一个例子:

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);
}

我的自定义 webview 现在看起来像这样,特别注意最后两种方法:

/**
 * 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;
    }
}

抱歉,我无法详细说明为什么这可以解决问题。我只能假设它与焦点有关,并且动态禁用它是一种享受:)

** 更新 (12/11/12) **

设法解决了上述两个问题。这似乎是 webview 的焦点问题。我的代码现在看起来像这样

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

我建议确保将可聚焦属性显式设置为“true”或调用 setFocusable(true)。

于 2012-10-16T22:25:39.127 回答