Android は、Web ページを処理するための非常に強力な WebView コントロールを提供します。Web ページでは、JavaScript も非常に重要なスクリプトです。この記事では、JavaコードとJavaScriptコード間の相互呼び出しを実装する方法を紹介します。
Javaとjsのやりとりを実現するととても便利です。通常は次の手順のみが必要です。
WebView は JavaScript スクリプトの実行を有効にします
WebView は、JavaScript 呼び出しの対話型インターフェイスを設定します。
クライアントと Web ページは、相互に呼び出すコードを記述します。
説明の便宜上、すべてのコードを最初に掲載しています
Javaコード
package com.example.javajsinteractiondemo; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.webkit.JavascriptInterface; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends Activity { private static final String LOGTAG = "MainActivity"; @SuppressLint("JavascriptInterface") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final WebView myWebView = (WebView) findViewById(R.id.myWebView); WebSettings settings = myWebView.getSettings(); settings.setJavaScriptEnabled(true); myWebView.addJavascriptInterface(new JsInteration(), "control"); myWebView.setWebChromeClient(new WebChromeClient() {}); myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); testMethod(myWebView); } }); myWebView.loadUrl("file:///android_asset/js_java_interaction.html"); } private void testMethod(WebView webView) { String call = "javascript:sayHello()"; call = "javascript:alertMessage(\"" + "content" + "\")"; call = "javascript:toastMessage(\"" + "content" + "\")"; call = "javascript:sumToJava(1,2)"; webView.loadUrl(call); } public class JsInteration { @JavascriptInterface public void toastMessage(String message) { Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } @JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); } } }
フロントエンドWebコード
<html> <script type="text/javascript"> function sayHello() { alert("Hello") } function alertMessage(message) { alert(message) } function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) } </script> Java-Javascript Interaction In Android </html>
呼び出し形式はウィンドウです.jsInterfaceName.methodName(parameterValues ) この例では、注入インターフェイス名として control を使用します。
function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
webViewがjsを呼び出す基本形式はwebView.loadUrl("javascript:methodName(parameterValues)")です
String call = "javascript:sayHello()"; webView.loadUrl(call);
パラメータ値としての strings では二重引用符をエスケープする必要があることに注意してください。
String call = "javascript:alertMessage(\"" + "content" + "\")"; webView.loadUrl(call);
Android 4.4 より前の Android には、js 関数を直接呼び出して値を取得するメソッドが提供されていなかったため、それ以前は、Java が js メソッドを呼び出し、js メソッドを呼び出すという一般的な考え方がありました。 Java コードを再度呼び出して値を返します。
1.Javaがjsコードを呼び出し
String call = "javascript:sumToJava(1,2)"; webView.loadUrl(call);
2.js関数の処理をjavaメソッドを呼び出して結果を返す
function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
3.Javaがコールバックメソッドでjs関数の戻り値を取得
@JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); }
後Android 4.4 では、evaluateJavaScript を使用するだけです。これは、戻り値を持つ js メソッドの簡単な対話型の例です
function getGreetings() { return 1; }
Java コードを使用するときに呼び出すには、evaluateJavascript メソッドを使用します
private void testEvaluateJavascript(WebView webView) { webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.i(LOGTAG, "onReceiveValue value=" + value); }}); }
結果を出力します
I/MainActivity( 1432): onReceiveValue value=1
注意
上記は、戻り値を String に制限しています。単純な型の場合は、文字列に変換して返します。複雑な データ型 の場合は、文字列形式の json の形式で返すことをお勧めします。
evaluateJavascriptメソッドはUIスレッド(メインスレッド)で呼び出す必要があるため、onReceiveValueもメインスレッドで実行されます。
WebChromeClientを設定する必要はありません。次のコードに従って設定してください
myWebView.setWebChromeClient(new WebChromeClient() {});
問題は、Webページのjsコードが存在しません読み込みが完了した後、jsメソッドが呼び出されます。解決策は、Web ページが読み込まれた後に js メソッドを呼び出すことです
myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //在这里执行你想调用的js函数 } });
問題がバージョン 4.2 以降のマシンでのみ発生する場合上記の場合、それはシステムです。セキュリティ制限の問題です。 Android のドキュメントには次のように書かれています
注意: targetSdkVersion を 17 以降に設定している場合は、Web ページのコードで使用できるようにするメソッドに @JavascriptInterface アノテーションを追加する必要があります (メソッドはパブリックである必要もあります)。注釈を提供しない場合、Android 4.2 以降で実行している場合、Web ページからメソッドにアクセスできなくなります。
中国語の意味は
警告: プログラムのターゲット プラットフォームが 17 以降の場合、@JavascriptInterface アノテーション は、Web ページに公開される呼び出し可能なメソッドに追加する必要があります (このメソッドはパブリックである必要があります)。これを行わないと、Web ページはプラットフォーム 4.2 以降のメソッドにアクセスできなくなります。
targetSdkVersionを17以降に設定し、@JavascriptInterfaceアノテーションを導入します
@JavascriptInterfaceという名前のアノテーションインターフェイスを自分で作成して導入します。このインターフェースを混同しないように注意してください。
@JavascriptInterface コードを作成してください
public @interface JavascriptInterface { }
難読化されていないコードが正常に実行される場合、難読化されたバージョンのコードはエラーを実行し、Uncaught TypeError: Object [object Object] has no method というプロンプトが表示されます。難読化された例外処理を行っていません。 難読化されたファイルに次のようなコードを追加します
-keep class com.example.javajsinteractiondemo$JsInteration { *; }
フィルター ログでこの問題が発見されました。
E/StrictMode( 1546): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c}, FYI main Looper is Looper (main, tid 1) {528712d4}) E/StrictMode( 1546): at android.webkit.WebView.checkThread(WebView.java:2063) E/StrictMode( 1546): at android.webkit.WebView.loadUrl(WebView.java:794) E/StrictMode( 1546): at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27) E/StrictMode( 1546): at android.os.Handler.dispatchMessage(Handler.java:102) E/StrictMode( 1546): at android.os.Looper.loop(Looper.java:136) E/StrictMode( 1546): at android.os.HandlerThread.run(HandlerThread.java:61)
js 呼び出し後の Java コールバック スレッドはメインスレッドではありません。ログを出力すると、
ThreadInfo=Thread[WebViewCoreThread,5,main]
を確認できます。 上記の例外を解決するには、メイン スレッドに Webview 操作を追加するだけです。
りー以上がAndroid における Java と JavaScript の相互作用の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。