Hướng dẫn android webview call javascript function - android webview gọi hàm javascript

Sửa đổi câu trả lời của @ilya_gazman

    private void callJavaScript(WebView view, String methodName, Object...params){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("javascript:try{");
        stringBuilder.append(methodName);
        stringBuilder.append("(");
        String separator = "";
        for (Object param : params) {               
            stringBuilder.append(separator);
            separator = ",";
            if(param instanceof String){
                stringBuilder.append("'");
            }
                stringBuilder.append(param.toString().replace("'", "\\'"));
            if(param instanceof String){
                stringBuilder.append("'");
            }

        }
        stringBuilder.append(")}catch(error){console.error(error.message);}");
        final String call = stringBuilder.toString();
        Log.i(TAG, "callJavaScript: call="+call);


        view.loadUrl(call);
    }

sẽ tạo chính xác các cuộc gọi JS, ví dụ:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}

Lưu ý rằng các đối tượng sẽ không được truyền chính xác - nhưng bạn có thể tuần tự hóa chúng trước khi truyền dưới dạng đối số.

Ngoài ra, tôi đã thay đổi nơi lỗi, tôi đã chuyển nó sang nhật ký bảng điều khiển có thể được nghe bởi:

    webView.setWebChromeClient(new CustomWebChromeClient());

và khách hàng

class CustomWebChromeClient extends WebChromeClient {
    private static final String TAG = "CustomWebChromeClient";

    @Override
    public boolean onConsoleMessage(ConsoleMessage cm) {
        Log.d(TAG, String.format("%s @ %d: %s", cm.message(),
                cm.lineNumber(), cm.sourceId()));
        return true;
    }
}

WebView là một thành phần đặc biệt trong Android đóng vai trò là loại trình duyệt tích hợp bên trong các ứng dụng Android. Nếu bạn muốn thực thi mã HTML, CSS hoặc JavaScript trong ứng dụng Android của bạn hoặc bạn cần cho phép người dùng truy cập URL mà không cần rời khỏi ứng dụng của bạn, WebView là cách để đi. Thành phần này không được sử dụng rất thường xuyên, nhưng trong một số trường hợp, sử dụng WebView chỉ đơn giản là sự đánh đổi tốt nhất với các yêu cầu.

Do đó, trong bài đăng này, tôi sẽ giải thích cách thiết lập giao tiếp giữa mã bản địa trên mạng và phần bên trong của WebView trong các ứng dụng Android, có thể là nhiệm vụ thách thức đáng ngạc nhiên.

HTML, CSS và JavaScript cho Android Webview

Với mục đích của hướng dẫn này, hãy tưởng tượng rằng WebView của bạn thực thi mã sau:




    
    Title
    



Don Tiết lo lắng nếu chức năng này không có ý nghĩa. Tôi đã thiết kế nó cho mục đích của hướng dẫn này, vì vậy tôi sẽ đề cập đến các phần cụ thể của mã này trong các phần sau.

Tùy thuộc vào yêu cầu của bạn, bạn có thể tìm nạp nội dung của WebView từ Web bằng phương thức

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
5 hoặc bạn có thể liên kết mã trực tiếp (ví dụ: sau khi tải nó từ tài sản) bằng cách sử dụng
callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
6. Các cách tiếp cận sau đây sẽ hoạt động với một trong những phương pháp này.

Bật hỗ trợ JavaScript WebView

Theo HTML ở trên, nút trên cùng sẽ thay đổi màu sắc của chính nó khi bạn nhấp vào nó. Tuy nhiên, trong thực tế, nếu bạn chỉ cần đẩy mã này vào WebView, rất có thể nó sẽ không làm gì cả. Lý do cho điều này là hỗ trợ JavaScript trong WebView bị tắt theo mặc định, do đó, bạn sẽ cần phải kích hoạt thủ công. Đây là một biện pháp phòng ngừa bảo mật được thúc đẩy bởi thực tế là thực hiện mã JavaScript ngẫu nhiên có thể gây rủi ro từ quan điểm bảo mật.

Để bật JavaScript bên trong WebView, hãy thực hiện lệnh này:

webView.settings.javaScriptEnabled = true

Sau đó, nút nên hoạt động như mong đợi.

Đánh giá mã JavaScript bên ngoài bên trong WebView

Ví dụ trước đã chứng minh việc thực hiện mã JavaScript có bên trong HTML ban đầu. Nhưng điều gì sẽ xảy ra nếu bạn muốn tiêm mã từ bên ngoài thì sao? Nói cách khác, điều gì sẽ xảy ra nếu bạn muốn đóng gói mã JavaScript cùng với mã bản địa trên mạng, và sau đó đánh giá nó với phạm vi nội dung của WebView khi chạy? Nhập phương thức

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
7.

Ví dụ: mã gốc sau sẽ dẫn đến việc thay đổi màu nền của WebView thành màu xanh:

webView.evaluateJavascript("document.body.style.background = 'blue';", null)

Đánh giá mã JavaScript bên ngoài bên trong WebView và trả về giá trị

Trong ví dụ trước, tôi đã chuyển một số mã JavaScript vào WebView và đánh giá nó. Đó là giao tiếp một chiều. Có cách nào để sử dụng một cách tiếp cận tương tự, nhưng cũng trả lại một số dữ liệu trở lại phía bản địa? Có, có!

Mã này sẽ hiển thị thông báo bánh mì nướng bằng nội dung của phần tử nhập

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
8 bên trong WebView:

webView.evaluateJavascript("(function() { return document.getElementById('toastMessage').value; })();") { returnValue ->
    Toast.makeText(requireContext(), returnValue, Toast.LENGTH_SHORT).show()
}

Lưu ý cú pháp liên quan hơn của mã JavaScript ở đây. Mặc dù trong ví dụ trước, tôi chỉ có thể viết logic JavaScript, bây giờ tôi cũng phải gửi nó vào một hàm ẩn danh và đánh giá chức năng đó.

Ngoài ra, nếu bạn chạy mã trên, bạn sẽ nhận thấy rằng văn bản được hiển thị trong bánh mì nướng được đặt trong các trích dẫn kép. Điều đó bởi vì giá trị trả về từ hàm JavaScript được gói vào giá trị JSON, đối tượng JSON hoặc mảng JSON (tùy thuộc vào những gì chức năng thực sự trả về) trước khi nó chuyển đến cuộc gọi lại gốc của bạn. Do đó, bạn sẽ cần phải mở ra giá trị trả về để lấy dữ liệu gốc.

Gọi chức năng JavaScript bên trong WebView từ mã Android gốc

Bây giờ, hãy để thảo luận về một chút trường hợp sử dụng khác nhau. Hãy tưởng tượng rằng bạn biết rằng có một chức năng JavaScript cụ thể bên trong WebView và bạn muốn gọi nó từ bên ngoài. Làm thế nào bạn sẽ đi về điều này?

Chà, cú pháp rất giống nhau, nhưng, thay vì xác định logic của riêng bạn, chỉ cần chỉ định tên của hàm để gọi:

webView.evaluateJavascript("getToastMessage();") { returnValue ->
    Toast.makeText(requireContext(), returnValue, Toast.LENGTH_SHORT).show()
}

Chuyển tham số cho chức năng JavaScript bên trong WebView

Nếu bạn sẽ gọi các chức năng được xác định trước bên trong WebView, bạn cũng có thể cần truyền các tham số bổ sung vào chúng. Cú pháp khá đơn giản:

webView.evaluateJavascript("concatenateStrings('${arg1}', '${arg2}');") { returnValue ->
    Toast.makeText(requireContext(), returnValue, Toast.LENGTH_SHORT).show()
}

Thật không may, sự đơn giản rõ ràng của phương pháp này là sai lệch. Nếu bạn có thể đảm bảo rằng các đối số won có chứa bất kỳ ký tự đặc biệt nào, thì bạn sẽ ổn. Nếu không, bạn có thể gặp vấn đề. Ví dụ: nếu bất kỳ đối số nào trong ví dụ trên sẽ chứa ký tự trích dẫn duy nhất, mã JavaScript kết quả sẽ không hợp lệ. Ngoài ra, nếu các đối số có thể là đa dòng, tốt hơn là bạn nên coi chừng.

Giải pháp cho vấn đề này là thoát khỏi tất cả các ký tự đặc biệt trong các đối số trước khi bạn xây dựng mã JavaScript. Các chi tiết, tuy nhiên, không nằm trong phạm vi của bài viết này. Có rất nhiều thông tin về việc thoát khỏi các đối số JavaScript ngoài kia, vì vậy, bây giờ, bạn biết về cạm bẫy này, bạn có thể tìm kiếm nó.

Gọi mã Android gốc từ bên trong WebView

Cho đến nay, tôi đã trình diễn cách bắt đầu các luồng khác nhau liên quan đến nội dung WebView từ phía bản địa. Tuy nhiên, trong một số trường hợp, bạn muốn thực hiện ngược lại chính xác và gọi đến mã gốc từ bên trong chính WebView. Điều đó có thể, nhưng giải pháp có liên quan nhiều hơn một chút.

Đầu tiên, trong mã gốc của bạn, bạn cần xác định giao diện gốc của Google, sẽ được tiếp xúc với mã JavaScript bên trong WebView:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
0

Thực tế là giao diện này yêu cầu

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
9 chỉ là một ví dụ, nhưng chú thích
    webView.setWebChromeClient(new CustomWebChromeClient());
0 là bắt buộc. Về cơ bản, nó chỉ định các phương thức mà mã JavaScript sẽ có thể xem.

Khi bạn đã xác định giao diện này, bạn cần thêm nó vào WebView:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
1

Đối số đầu tiên là chính giao diện và đối số thứ hai là tên của trường hợp đó bên trong WebView. Nó không yêu cầu họ giống nhau, nhưng điều này nghe có vẻ như là một lựa chọn mặc định hợp lý.

Sau hai bước trên, bạn sẽ có thể gọi các phương thức trên giao diện gốc này, từ bên trong mã JavaScript bên trong WebView:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
2

Có tính đến thực tế là phương thức

    webView.setWebChromeClient(new CustomWebChromeClient());
1 trong mã gốc của bạn sẽ được gọi trên một luồng nền đặc biệt, vì vậy nó phải an toàn cho luồng.

Truy cập các thông báo bảng điều khiển JavaScript WebView trong mã Android gốc

Nếu bạn sẽ làm việc với WebView trong Android, rất có thể bạn sẽ muốn đọc các tin nhắn giao diện điều khiển của nó. Đây là một công cụ tốt để ghi nhật ký và gỡ lỗi cơ bản.

Tuy nhiên, nếu bạn chỉ cần thêm câu lệnh này bên trong mã JavaScript của mình, bạn sẽ giành được bất kỳ đầu ra nào:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
3

Để chặn các thông báo bảng điều khiển bên trong mã gốc, bạn sẽ cần sử dụng thủ thuật sau:

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}
4

Trong trường hợp này, tôi chỉ cần in các tin nhắn điều khiển vào logcat Android, nhưng bạn có thể làm bất cứ điều gì bạn muốn với chúng.

Sự kết luận

WebView là một thành phần thích hợp và một chút lạ, nhưng nó có các trường hợp sử dụng. Vì vậy, nếu bạn không gặp may và phải đối phó với WebView trong ứng dụng của bạn, thì ít nhất, tôi hy vọng rằng bài viết này sẽ làm cho hành trình của bạn mượt mà hơn một chút.

Làm thế nào để sử dụng JavaScript trong Android Webview?

Bật JavaScript JavaScript bị vô hiệu hóa trong WebView theo mặc định. Bạn có thể kích hoạt nó thông qua các trang web được đính kèm với WebView của bạn. Bạn có thể truy xuất các cài đặt web với getSinstall (), sau đó bật javaScript bằng setJavascriptenable (). WebView myWebView = (WebView) FindViewById (r.retrieve WebSettings with getSettings() , then enable JavaScript with setJavaScriptEnabled() . WebView myWebView = (WebView) findViewById(R.

Làm thế nào để gọi phương thức JavaScript trong Android?

Để sử dụng JavaScript, bạn cần bật nó bằng cách gọi phương thức setJavascriptEnables () trên đối tượng WebSinstall.calling the setJavaScriptEnabled() method on the WebSettings object.

Làm thế nào để đưa JavaScript vào một WebView?

Tiêm JavaScript vào Android Webview..
Bằng cách sử dụng LoadUrl () -> API Cấp 18 trở xuống.Với loadUrl (), giao diện người dùng sẽ được làm mới khi tập lệnh được áp dụng và nó không trả về bất kỳ giá trị nào.....
Bằng cách sử dụng đánh giájavascript () -> API cấp 19 trở lên ..

Giao diện JavaScript trong WebView trong Android là gì?

Thông qua giao diện, WebView cho phép chúng tôi kết nối mã JavaScript với mã Android.Lớp cung cấp giao diện cho JS phải được thông qua, cùng với tên sẽ được sử dụng để hiển thị thể hiện trong JS (ví dụ: Andro Android,).enables us to connect JavaScript code to Android code. The class that provides the interface for JS must be passed, along with the name that will be used to show the instance in JS (for example, “Android”).