在做腾讯微博的第三方登录的时候,由于要兼容2.2以下的版本,不得已使用了oauth2.0和oauth1两种授权机制来处理。要用oauth1,用http协议,只有自己定义webview了。但是在使用2.1的sdk测试该webview的时候,出现了一个ANR。大概的错误日志如下:
01-01 22:56:38.063: E/AndroidRuntime(15404): java.lang.NullPointerException 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.webkit.WebView.getSettings(WebView.java:2759) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.webkit.WebView.onWindowFocusChanged(WebView.java:3585) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.View.dispatchWindowFocusChanged(View.java:3731) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:657) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:661) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:661) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:661) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:661) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.view.ViewRoot.handleMessage(ViewRoot.java:1822) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.os.Handler.dispatchMessage(Handler.java:99) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.os.Looper.loop(Looper.java:123) 01-01 22:56:38.063: E/AndroidRuntime(15404): at android.app.ActivityThread.main(ActivityThread.java:4367) 01-01 22:56:38.063: E/AndroidRuntime(15404): at java.lang.reflect.Method.invokeNative(Native Method) 01-01 22:56:38.063: E/AndroidRuntime(15404): at java.lang.reflect.Method.invoke(Method.java:521) 01-01 22:56:38.063: E/AndroidRuntime(15404): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 01-01 22:56:38.063: E/AndroidRuntime(15404): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 01-01 22:56:38.063: E/AndroidRuntime(15404): at dalvik.system.NativeStart.main(Native Method)
public void onPageStarted(final WebView view, String url, Bitmap favicon) { if (url.indexOf("xxxxx") != -1) { view.destroyDrawingCache(); view.destroy(); finish(); } super.onPageStarted(view, url, favicon); }
纠结了老半天,后来看了一下WebView的destroy()的文档。如下:
Destroy the internal state of the WebView. This method should be called after the WebView has been removed from the view system. No other methods may be called on a WebView after destroy.
原来是在destroy()方法后面调用了finish,导致ANR。具体的原因不详,但从文档中应该可以看出是提前调用了destroy()方法导致WebViewClient后续的方法中出现了空指针。解决办法就是将destroy()方法放在WebViewClient的onPageFinished()方法中,而onPageStarted方法中只做finish()的操作。如下:
WebViewClient client = new WebViewClient(){ @Override public void onPageStarted(final WebView view, String url, Bitmap favicon) { if (url.indexOf("xxxxx") != -1) { //... finish(); } super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { if (url.indexOf("xxxxx") != -1) { view.destroyDrawingCache(); view.destroy(); } super.onPageFinished(view, url); } };