Android 開発プロセスでは、WebView の使用が広く行われており、WebView はウェブページの読み込みに使用されます。たとえば、ニュースページの読み込み、アプリ内リンクの開き、支払い情報ページの表示などに使用されます。では、Android 開発で WebView のコンテンツとの相互作用をどのように行うのでしょうか。このような相互作用は主に Java と JavaScript の間の相互呼び出しです。以下に、WebView 内の画像のクリックイベントにどのように応答するかを実装します。
- キーメソッド
- 具体的な実装
- 表示効果
キーメソッド#
setJavaScriptEnabled()#
WebView が JavaScript スクリプトをサポートするかどうかを設定します。デフォルトではサポートされていません。
public abstract void setJavaScriptEnabled(boolean flag);
addJavascriptInterface()#
Java オブジェクトを WebView に注入し、そのオブジェクトが JavaScript のメインフレームワークのコンテキストに注入されるようにします。JavaScript からそのオブジェクトのメソッドにマッピングされた Java オブジェクトの名前を使用してアクセスできます。JavaScript からアクセスできるのは、@JavascriptInterface アノテーションが付いているパブリックメソッドのみで、API レベル 17 以上で使用できます。
API レベル 16 およびそれ以前の API では、すべてのパブリックメソッド(継承されたメソッドも含む)が JavaScript からアクセスできます。ただし、ページが再読み込みされる前に Java オブジェクトが JavaScript に注入されていない場合、Java メソッドの呼び出しは効果がありません。
重要な注意:このメソッドは JavaScript がアプリケーションを制御することを許可するため、非常に強力な機能ですが、API レベル 16 およびそれ以前のバージョンでは一定のリスクが存在します。安全な方法は、このメソッドを Android 4.2 以上のバージョンで使用することです。より低いバージョンの場合、JavaScript は注入されたオブジェクトのパブリックフィールドにアクセスするためにリフレクションを使用できます。WebView でこのメソッドを使用すると、信頼できないコンテンツが攻撃者によって利用され、アプリケーションが Java コードを実行する可能性があるため、スレッドセーフに注意する必要があります。また、Android 5.0 以上では、注入された Java オブジェクトのメソッドには一定の制限があります。
public void addJavascriptInterface(Object object, String name) {}
具体的な実装#
大まかなアイデアは、WebView 内の画像がクリックイベントに応答し、クリックされた画像を表示するために Android インターフェースを呼び出すことです。以下に手順を示します。
- WebView で JavaScript スクリプトをサポートするように設定します。
- JavaScript と通信するためのクラスと JavaScript から呼び出されるメソッドを作成します。
- WebView に表示するコンテンツをロードします。
- addJavascriptInterface メソッドを使用して Java オブジェクトを JavaScript にマッピングします。
- JavaScript でマッピングオブジェクトのメソッドを呼び出して画像を表示するアクティビティを開きます。
- JavaScript のメソッドを呼び出します。
ステップ 1#
WebView で JavaScript スクリプトをサポートするように設定します。
// JavaScriptをサポートするように設定
webSettings.setJavaScriptEnabled(true);
ステップ 2#
JavaScript と通信するためのクラスと JavaScript から呼び出されるメソッドを作成します。
/**
* JavaScriptと通信するJavaオブジェクトで、JavaScriptから呼び出されるメソッドを提供します。
* Created by jzman on 2017/7/20 0020.
*/
public class AndroidInterface {
private Context context;
public AndroidInterface(Context context) {
this.context = context;
}
/**
* @JavascriptInterfaceアノテーションを追加します
* JavaScriptから呼び出されるメソッド
*/
@JavascriptInterface
public void showImage(String imgUrl){
Intent intent = new Intent();
intent.putExtra("img",imgUrl);
intent.setClass(context,ImageActivity.class);
context.startActivity(intent);
}
}
ステップ 3#
WebView に表示するコンテンツをロードします。ここでは、assets ディレクトリの HTML ファイルをロードしています。
// assetsディレクトリのHTMLファイルをロード
webView.loadUrl("file:///android_asset/index.html");
ステップ 4#
addJavascriptInterface メソッドを使用して Java オブジェクトを JavaScript にマッピングします。
// Javaオブジェクトを注入し、JavaScriptにマッピングします
// パラメータ(JavaScriptと通信するオブジェクト、JavaScriptにマッピングするオブジェクト)
webView.addJavascriptInterface(new AndroidInterface(this),"imageListener");
ステップ 5#
JavaScript でタグを検索し、クリックイベント内でマッピングオブジェクトのメソッドを呼び出して画像を表示するアクティビティを開きます。
<script type="text/javascript">
function findImg(){
// imgタグを検索
var imgs = document.getElementsByTagName("img");
// imgタグを反復処理
for(var i=0; i<imgs.length; i++){
// 各タグにクリックイベントを設定
imgs[i].onclick = function(){
// imageListenerにマッピングされたJavaオブジェクト
window.imageListener.showImage(this.src);
}
}
}
</script>
ステップ 6#
JavaScript のメソッドを呼び出すために、Java オブジェクトが JavaScript に注入される前に呼び出されるようにするために、ページの読み込みが完了したときに javaScript のメソッドを呼び出す必要があります。
// WebViewClientを設定して関連するイベントを監視します
webView.setWebViewClient(new WebViewClient(){
// ページの読み込みが完了したらこのメソッドが呼び出されます
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// ページの読み込みが完了した後にJavaオブジェクトがJavaScriptに注入されるようにする
webView.loadUrl("javascript:findImg()");
}
});
表示効果#
ソースコードはこちらを参照してください:github