68

Android 4.4 で新しいevaluateJavascriptメソッドを使用しようとしていますが、返されるのは null の結果だけです。

webView1.evaluateJavascript("return \"test\";", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Log is written, but s is always null
    }
});

このメソッドに結果を返すにはどうすればよいですか?

更新:もう少し情報:

  1. INTERNET 権限セットを持っています
  2. 私は持っているsetJavascriptEnabled(true);
  3. アポストロフィ文字列を試しました: return 'test';,
  4. 試したJSオブジェクト:return { test: 'this' }
  5. console.log('test');正常に実行されています。
  6. targetSdkVersion次のように 19 に設定します。アプリが WebView を使用している場合

デバイス: Nexus 7 と Nexus 5 の両方 (ストック)

4

6 に答える 6

82

このサンプルで使用されている evaluateJavascript メソッドの例があります。

https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example

基本的に、WebView で実行する JavaScript が値を返す場合、それはコールバックで渡されます。

主な注意点は、OnReceiveValue で返される文字列は、返される内容に応じて、JSON 値、JSON オブジェクト、または JSON 配列のいずれかであるということです。

これについて注意すべきことは、単一の値を返す場合、JSON リーダーで setLenient(true) を使用して機能させる必要があることです。

     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // In KitKat+ you should use the evaluateJavascript method
        mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
            @TargetApi(Build.VERSION_CODES.HONEYCOMB)
            @Override
            public void onReceiveValue(String s) {
                JsonReader reader = new JsonReader(new StringReader(s));

                // Must set lenient to parse single values
                reader.setLenient(true);

                try {
                    if(reader.peek() != JsonToken.NULL) {
                        if(reader.peek() == JsonToken.STRING) {
                            String msg = reader.nextString();
                            if(msg != null) {
                                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
                            }
                        }
                    }
                } catch (IOException e) {
                    Log.e("TAG", "MainActivity: IOException", e);
                } finally {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        // NOOP
                    }
                }
            }
        });
    }

文字列応答にパーサーを引き続き使用する理由は、それが JSON 値に変換されるためです。つまり、引用符で囲まれます。

たとえば、あなたが行った場合:

mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints: "this"
    }
});

二重引用符で囲まれた文字列 this を出力します: "this"。

注目に値するその他の例:

mWebView.evaluateJavascript("(function() { return null; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints the string 'null' NOT Java null
    }
});

mWebView.evaluateJavascript("(function() { })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); //s is Java null
    }
});

mWebView.evaluateJavascript("(function() { return ''; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints "" (Two double quotes)
    }
});
于 2013-12-04T14:23:56.273 に答える
15

わかりました。これがJavascript 呼び出しresultの結果であることがわかります。あたかも Javascript コンソールにコマンドを入力したかのように。

したがって、結果を取得するには、関数でラップする必要があります。

webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints 'this'
    }
});

これも機能します:

webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints asd
    }
});

このメソッドは、Javascript オブジェクトも処理します。

webView1.evaluateJavascript("(function() { return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
    }
});
于 2013-11-05T14:06:43.577 に答える