WebView の JavaScript 連携はセキュリティに問題が残るとしても、やはり魅力的な使い方がある。
ページが読み込めなかった時、、
WebViewClient の onReceivedError が呼ばれるのでそこでエラー処理を書けばよいのだが、、
onPageFinished で判定したい場合に、JavaScript 連携を使ってしまう。
画面に出さない、裏で WebView を使った処理する時などに使えそうである。
注意しなければならないのは、上の「ページが見つかりませんでした」のエラーの場合、
onPageFinished は、2回呼ばれることだ。
onPageFinished で JavaScript による判定の結果実行されるインターフェースを以下のように用意する。
public interface PageFinishedListener{
public void onSuccess(String url);
public void onFailed(String url);
}
WebView の addJavascriptInterface でセットするインスタンスのクラス定義は以下のようにする。
getRname() が、addJavascriptInterface 実行のキー名を返すようになっている。
import android.webkit.WebView;
/**
* WebPageJsRelay
*/
public class WebPageJsRelay{
private int count;
private PageFinishedListener handle;
private String url;
private boolean isPages;
public WebPageJsRelay(PageFinishedListener handle){
count = 0;
this.handle = handle;
}
public final String getRname(){
return "jsrelay";
}
public final void triggerPageStarted(){
count = 0;
isPages = false;
}
public final void triggerPagefinished(WebView _view, String _url){
this.url = _url;
isPages = !isPages;
if (isPages){
_view.loadUrl("javascript:var g=document.getElementsByTagName('img');for(var i=0;i<g.length;i++){ jsrelay.imaged(g[i].src); }jsrelay.parse();");
}
}
public final void imaged(String src){
if ("file:///android_asset/webkit/android-weberror.png".equals(src)){
count++;
}
}
public final void parse(){
if ( count > 0){
count = 0;
handle.onFailed(url);
}else{
handle.onSuccess(url);
}
}
}
使用サンプルは、
WebView mWebView;
WebPageJsRelay mPageRelay;
:
:
mPageRelay = new WebPageJsRelay(new PageFinishedListener(){
@Override
public void onSuccess(String url){
// TODO ページが正常に読み込めた時の処理
}
@Override
public void onFailed(String url){
// TODO ページが読み込めなかった時の処理
}
});
mWebView.addJavascriptInterface(mPageRelay, mPageRelay.getRname());
mWebView.setWebViewClient(new WebViewClient(){
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon){
mPageRelay.triggerPageStarted();
}
@Override
public void onPageFinished(WebView view, String url){
mPageRelay.triggerPagefinished(view, url);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
// エラー受信時の処理
}
private Message mdontResend;
@Override
public void onFormResubmission(WebView view,Message dontResend,Message resend){
if (mdontResend != null){
mdontResend.sendToTarget();
return;
}
mdontResend = dontResend;
if (resend != null){
resend.sendToTarget();
mdontResend = null;
}
}
@Override
public void onReceivedHttpAuthRequest(WebView view,final HttpAuthHandler handler,String host,String realm){
handler.cancel();
}
});