Android Calling JavaScript functions in WebView

前端 未结 7 600
夕颜
夕颜 2020-11-22 04:14

I am trying to call some javascript functions sitting in an html page running inside an android webview. Pretty simple what the code

相关标签:
7条回答
  • 2020-11-22 04:51

    Yes you have the syntax error. If you want to get your Javascript errors and printing statements in your logcat you must implement the onConsoleMessage(ConsoleMessage cm) method in your WebChromeClient. It gives the complete stack traces like Web console(Inspect element). Here is the method.

    public boolean onConsoleMessage(ConsoleMessage cm) 
        {
            Log.d("Message", cm.message() + " -- From line "
                                 + cm.lineNumber() + " of "
                                 + cm.sourceId() );
            return true;
        }
    

    After implementation you will get your Javascript errors and print statements (console.log) on your logcat.

    0 讨论(0)
  • 2020-11-22 04:54

    I created a nice wrapper to call JavaScript methods; it also shows JavaScript errors in log:

    private void callJavaScript(String methodName, Object...params){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("javascript:try{");
        stringBuilder.append(methodName);
        stringBuilder.append("(");
        for (int i = 0; i < params.length; i++) {
            Object param = params[i];
            if(param instanceof String){
                stringBuilder.append("'");
                stringBuilder.append(param.toString().replace("'", "\\'"));
                stringBuilder.append("'");
            }
            if(i < params.length - 1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append(")}catch(error){Android.onError(error.message);}");
        webView.loadUrl(stringBuilder.toString());
    }
    

    You need to add this too:

    private class WebViewInterface{
    
        @JavascriptInterface
        public void onError(String error){
            throw new Error(error);
        }
    }
    

    And add this interface to your webview:

    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");
    
    0 讨论(0)
  • 2020-11-22 04:57
    public void run(final String scriptSrc) { 
            webView.post(new Runnable() {
                @Override
                public void run() { 
                    webView.loadUrl("javascript:" + scriptSrc); 
                }
            }); 
        }
    
    0 讨论(0)
  • 2020-11-22 05:03

    I figured out what the issue was : missing quotes in the testEcho() parameter. This is how I got the call to work:

    myWebView.loadUrl("javascript:testEcho('Hello World!')");
    
    0 讨论(0)
  • 2020-11-22 05:03

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </RelativeLayout>
    

    MainActivity.java

    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    
    import com.bluapp.androidview.R;
    
    public class WebViewActivity3 extends AppCompatActivity {
        private WebView webView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_web_view3);
            webView = (WebView) findViewById(R.id.webView);
            webView.setWebViewClient(new WebViewClient());
            webView.getSettings().setJavaScriptEnabled(true);
            webView.loadUrl("file:///android_asset/webview1.html");
    
    
            webView.setWebViewClient(new WebViewClient(){
                public void onPageFinished(WebView view, String weburl){
                    webView.loadUrl("javascript:testEcho('Javascript function in webview')");
                }
            });
        }
    }
    

    assets file

    <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head><title>WebView1</title>
    <meta forua="true" http-equiv="Cache-Control" content="max-age=0"/>
    </head>
    
    <body style="background-color:#212121">
    <script type="text/javascript">
    function testEcho(p1){
    document.write(p1);
    }
    </script>
    </body>
    
    </html>
    
    0 讨论(0)
  • 2020-11-22 05:04

    Modification of @Ilya_Gazman answer

        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);
        }
    

    will correctly create JS calls e.g.

    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);}
    

    Note that objects will not be passed correctly - but you can serialize them before passing as an argument.

    Also I've changed where the error goes, I've diverted it to the console log which can be listened by:

        webView.setWebChromeClient(new CustomWebChromeClient());
    

    and client

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题