1. 程式人生 > >webview原生和JavaScript(js)互動傳值的幾種方式

webview原生和JavaScript(js)互動傳值的幾種方式

說明:

安卓的原生和webview之間需要傳值等操作,下面是列了幾種他們傳值互動的幾種方式。

1、通過loadurl()來呼叫:

js方法:

function methodName(jsonParams) {
	//處理jsonParams
}

安卓呼叫:

String url = "javascript:" + methodName + "(" + jsonParams + ");
webView.loadUrl(url);

說明:

就是這麼簡單,直接呼叫 WebView 的loadUrl(url)方法,當然引數 url 是比較特殊,前面的javascript:偽協議讓我們可以通過一個連結來呼叫 JavaScript 函式,中間methodName是 JavaScript 中實現的函式,jsonParams是傳入的引數。關於後面的void(0)。

2、addJavascriptInterface注入:

程式碼:

webView.addJavascriptInterface(new JsObject(), "injectedObject"); // 只有頁面再載入,該物件才可見

說明:

只要原生的webview設定這個方法,原生和js之間是可以互相直接呼叫的(現在這個方法出現了漏洞,有些app市場監測到這個方法,就會不讓上傳app),addJavascriptInterface這種方式非常簡單好用。但是這種方式在 Android 4.2之前的版本中存在安全問題:在4.2之前被注入的物件的所有公共方法(包括從父類繼承過來的方法)都可以被訪問到;在4.2以後,只有通過@JavascriptInterface註解的公共方法才能被訪問。具體請看這篇

WebView中介面隱患與手機掛馬利用

3、shouldOverrideUrlLoading

說明:

這個方法大家都知道是攔截url訪問的,這裡的傳值就是把值放在url裡面傳進來,進行攔截處理值:

程式碼:

webView.setWebViewClient(new WebViewClient() {//攔截url
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                LogUtils.d("請求-->總url:" + url);
                if (url.startsWith("mandaobridge")) {//如果不是正常url,測作為引數傳遞來處理(實現了傳值操作)
                    handRequest(url);
                } else {//如果是正常url就載入url
                    view.loadUrl(url);
                }
                return true;
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);

                //UiUtils.showToast("出錯");
            }
        });

4、alert、confirm、和prompt

說明:

這三個本來是原生webview給網頁彈框的一些呼叫,但是彈框就會有提示語,這裡就用這些提示語來作為值傳遞。

程式碼:

private void init webView() {     
        webView = new WebView(context);  
        WebSettings webSettings = webView.getSettings();  
        webSettings.setJavaScriptEnabled(true);//允許網頁使用js  
        webView.setWebChromeClient(new WebChromeClient() {//允許有alert彈出框  
            @Override  
            public void onReceivedTitle(WebView view, String title) {  
                super.onReceivedTitle(view, title);  
                webTitle = title;  
            }  
  
            /**      
             * 處理alert彈出框      
             */         
            @Override         
            public boolean onJsAlert(WebView view,String url,          
                                     String message,JsResult result) {          
                Log.d(LOG_TAG,"onJsAlert:"+message);          
              //  mReusultText.setText("Alert:"+message);          
              /*  //對alert的簡單封裝        
                new AlertDialog.Builder(PhoneTest.this).        
                    setTitle("Alert").setMessage(message).setPositiveButton("OK",        
                    new DialogInterface.OnClickListener() {        
                        @Override       
                        public void onClick(DialogInterface arg0, int arg1) {        
                           //TODO        
                       }        
                }).create().show();        
                */    
                result.confirm();          
                return super.onJsConfirm(view,url,message, result);          
            }          
             
            /**      
             * 處理confirm彈出框      
             */         
            @Override         
            public boolean onJsConfirm(WebView view, String url, String message,          
                    JsResult result) {          
                Log.d(LOG_TAG, "onJsConfirm:"+message);          
                mReusultText.setText("Confirm:"+message); //捕獲彈框訊息給原生賦值,相當於傳值了   
                //對confirm的簡單封裝          
                new AlertDialog.Builder(PhoneTest.this).          
                    setTitle("Confirm").setMessage(message).setPositiveButton("OK",          
                    new DialogInterface.OnClickListener() {          
                        @Override         
                        public void onClick(DialogInterface arg0, int arg1) {          
                           //TODO          
                       }          
                }).create().show();      
                result.confirm();          
                return true;    
                //如果採用下面的程式碼會另外再彈出個訊息框,目前不知道原理    
                //return super.onJsConfirm(view, url, message, result);          
            }          
             
            /**      
             * 處理prompt彈出框      
             */         
            @Override         
            public boolean onJsPrompt(WebView view, String url, String message,          
                    String defaultValue, JsPromptResult result) {          
                Log.d(LOG_TAG,"onJsPrompt:"+message);          
                mReusultText.setText("Prompt input is :"+message);          
                result.confirm();          
                return super.onJsPrompt(view, url, message, message, result);          
            }          
      
        });  
}    

具體使用方法我新寫了一篇部落格:android webview獲取js中的alert、confirm、和prompt,以及獲取其值

5、evaluateJavascript

說明:

evaluateJavascript這個方法是原生webview直接呼叫網頁js的方法,並且得到js方法的返回值,很方便,實現了原生和js無縫對接,但是這個有版本限制sdk大於19才能用,中國的市場4.4一下的手機多了去了,有很大的侷限性。

程式碼:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//sdk>19才有用
            final String[] paths = moduleUrl.split("/", 3);
            LogUtils.d("paths:" + paths[0] + "..." + paths[1] + "...." + paths[2]);


            String script = "mandaobridge.getParams('" + paths[2] + "')";
            webView.evaluateJavascript(script, new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String responseJson) {
                    LogUtils.d("呼叫js返回值:" + paths[2] + "--" + responseJson);
                    analyParams(paths, responseJson);
                }
            });
        } else {//sdk<19後,通過prompt來獲取
            String[] paths = moduleUrl.split("/", 3);
            promptMap.put(paths[2], paths);
            webView.loadUrl("javascript:mandaobridge.getParams('!" + paths[2] + "')");
            LogUtils.d("Prompt請求:" + "mandaobridge.getParams('!" + paths[2] + "')");
        }

總結:

以上幾種原生和網頁js之間的互動慢慢繼續完善使用方法和使用問題。轉載說明出處!