Pertanyaan Bagaimana cara mengembalikan nilai dari javascript di webview android?


Saya ingin mendapatkan nilai kembali dari Javascript di Android. Saya bisa melakukannya dengan iPhone, tetapi saya tidak bisa dengan Android. Saya menggunakan loadUrl, tetapi mengembalikan void sebagai ganti objek. Adakah yang bisa membantu saya? Terima kasih.


64
2017-07-21 11:14


asal


Jawaban:


Berikut ini adalah cara Anda mencapai hal itu:

Tambahkan Klien ini ke WebView Anda:

final class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d("LogTag", message);
            result.confirm();
            return true;
        }
    }

Sekarang dalam panggilan javascript Anda lakukan:

webView.loadUrl("javascript:alert(functionThatReturnsSomething)");

Sekarang dalam "pesan" panggilan onJsAlert akan berisi nilai yang dikembalikan.


61
2017-07-26 20:19



Sama dengan Keith tetapi jawaban yang lebih pendek

webView.addJavascriptInterface(this, "android");
webView.loadUrl("javascript:android.onData(functionThatReturnsSomething)");

Dan implementasikan fungsinya

@JavascriptInterface
public void onData(String value) {
   //.. do something with the data
}

Jangan lupa untuk menghapus onData dari proguard daftar (jika Anda telah mengaktifkan proguard)


57
2017-09-29 10:42



Menggunakan addJavascriptInterface() untuk menambahkan objek Java ke lingkungan Javascript. Apakah Javascript Anda memanggil metode pada objek Java untuk memberikan "nilai kembaliannya".


17
2017-07-21 12:36



Inilah yang saya dapatkan hari ini. Benangnya aman, cukup efisien, dan memungkinkan eksekusi Javascript sinkron dari Java untuk Android WebView.

Berfungsi di Android 2.2 dan lebih tinggi. (Memerlukan commons-lang karena saya memerlukan cuplikan kode saya dilewatkan ke eval () sebagai string Javascript. Anda dapat menghapus ketergantungan ini dengan membungkus kode tidak dalam tanda kutip, tetapi dalam function(){})

Pertama, tambahkan ini ke file Javascript Anda:

function evalJsForAndroid(evalJs_index, jsString) {
    var evalJs_result = "";
    try {
        evalJs_result = ""+eval(jsString);
    } catch (e) {
        console.log(e);
    }
    androidInterface.processReturnValue(evalJs_index, evalJs_result);
}

Kemudian, tambahkan ini ke aktivitas Android Anda:

private Handler handler = new Handler();
private final AtomicInteger evalJsIndex = new AtomicInteger(0);
private final Map<Integer, String> jsReturnValues = new HashMap<Integer, String>();
private final Object jsReturnValueLock = new Object();
private WebView webView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    webView = (WebView) findViewById(R.id.webView);
    webView.addJavascriptInterface(new MyJavascriptInterface(this), "androidInterface");
}

public String evalJs(final String js) {
    final int index = evalJsIndex.incrementAndGet();
    handler.post(new Runnable() {
        public void run() {
            webView.loadUrl("javascript:evalJsForAndroid(" + index + ", " +
                                    "\"" + StringEscapeUtils.escapeEcmaScript(js) + "\")");
        }
    });
    return waitForJsReturnValue(index, 10000);
}

private String waitForJsReturnValue(int index, int waitMs) {
    long start = System.currentTimeMillis();

    while (true) {
        long elapsed = System.currentTimeMillis() - start;
        if (elapsed > waitMs)
            break;
        synchronized (jsReturnValueLock) {
            String value = jsReturnValues.remove(index);
            if (value != null)
                return value;

            long toWait = waitMs - (System.currentTimeMillis() - start);
            if (toWait > 0)
                try {
                    jsReturnValueLock.wait(toWait);
                } catch (InterruptedException e) {
                    break;
                }
            else
                break;
        }
    }
    Log.e("MyActivity", "Giving up; waited " + (waitMs/1000) + "sec for return value " + index);
    return "";
}

private void processJsReturnValue(int index, String value) {
    synchronized (jsReturnValueLock) {
        jsReturnValues.put(index, value);
        jsReturnValueLock.notifyAll();
    }
}

private static class MyJavascriptInterface {
    private MyActivity activity;

    public MyJavascriptInterface(MyActivity activity) {
        this.activity = activity;
    }

    // this annotation is required in Jelly Bean and later:
    @JavascriptInterface
    public void processReturnValue(int index, String value) {
        activity.processJsReturnValue(index, value);
    }
}

9
2018-02-11 17:15



Solusi yang @Felix Khazin menyarankan pekerjaan, tetapi ada satu titik kunci yang hilang.

Panggilan javascript harus dilakukan setelah halaman web di WebView sudah dimuat. Tambahkan ini WebViewClient ke WebView, Bersama dengan WebChromeClient.

Contoh Lengkap:

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    WebView webView = (WebView) findViewById(R.id.web_view);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new MyWebViewClient());
    webView.setWebChromeClient(new MyWebChromeClient());
    webView.loadUrl("http://example.com");
}

private class MyWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished (WebView view, String url){
        view.loadUrl("javascript:alert(functionThatReturnsSomething())");
    }
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return false;
    }
}

private class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    Log.d("LogTag", message);
        result.confirm();
        return true;
    }
}

4
2018-04-21 18:29



Pada API 19+, cara terbaik untuk melakukan ini adalah menelepon evaluasikanJavascript di WebView Anda:

webView.evaluateJavascript("foo.bar()", new ValueCallback<String>() {
    @Override public void onReceiveValue(String value) {
        // value is the result returned by the Javascript as JSON
    }
});

Jawaban terkait dengan detail lebih lanjut: https://stackoverflow.com/a/20377857


3
2018-06-01 14:01