AndroidのWebViewで、これまで、addJavaScriptInterfaceを使って、ブラウザから、JavaネイティブのAndroid APIを呼び出していたのですが、セキュリティ的に問題があるために、Android 4.2以降では、普通にJavaのメソッドを呼び出せないようになりました。

AndroidのAPIマニュアルを見てみると、@JavascriptInterfaceがついているpublicメソッドのみアクセスできるとなっています。

// JavaScriptから呼び出したいメソッドを定義したクラス
class JsObject {
  //JavaScriptから呼び出したいメソッド
  @JavascriptInterface
  public String toString() { return "injectedObject"; }
}
// JavaインスタンスをWebViewに登録する
webView.addJavascriptInterface(new JsObject(), "injectedObject");
// 
webView.loadData("", "text/html", null);
// JsObjectのメソッドを呼び出す
webView.loadUrl("javascript:alert(injectedObject.toString())");

苦労したLolipop対応(ToT *

また、Android5.x(Lolipop:特に5.1)では、セキュリティがより厳しくなったようで、過去のAPIでコンパイルしたアプリでも、@JavascriptInterfaceをつけていないメソッドが見つからなくなるという問題が発生しています。

また、Lolipop以前では、Java関数の戻り値や引数に、ネイティブJavaオブジェクトを指定することができたのですが、Lolipop以降では、ネイティブなJavaオブジェクトは利用できなくなった様子。(これが分からず、何時間も無駄にしてしまったのです!!)

例えば、JavaScriptから、DBを開いて、そのDBに対してクエリを実行しようとするとき、DBを開いた関数の戻り値に、SQLiteDatabaseのオブジェクトを戻し、さらに、クエリを実行する際に、SQLiteDabaseのオブジェクトを与えていたのですが、どうやら、これが問題となっていた模様、DBのID番号を返す仕様に変更してみたら動いたのです。