android2.1バージョンでandroid.webkit.WebView.getSettingsのNullPointerException問題

3621 ワード

テンセント微博の第三者登録をする際、2.2以下のバージョンと互換性があるため、やむを得ずoauth 2を使用した.0とoauth 1の2つのライセンスメカニズムで処理されます.oauth 1を使うには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)

空のポインタ、WebSettings=webView.getSettings();onCreate()メソッドで処理されていますが、そもそも空のポインタは出ないのでしょうか?最初はonPageStarted()メソッドのコードは以下の通りで、このコードは2.1以上のバージョンで走っても問題ありません.
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);
	}
};

長い間悩んでいた問題をここに記録しておきます.Oauth2.0はOauth 1と一緒に使うのも、うんざりです.