1. 程式人生 > >安卓與JS互調之android webview addJavascriptInterface 的方法不能呼叫

安卓與JS互調之android webview addJavascriptInterface 的方法不能呼叫

以前一直覺著用HTML5Android app是一件很雞肋的事(勿噴,請恕小的見識少微笑)。

後來又發現很多大公司做的app中都或多或少的使用了html元素,比如微信、qq之類。

最近在網上閒逛發現一個IDE可以使用純html js css設計app併發布到多個平臺,並且更牛的是可以直接使用它提供的js api呼叫各種系統原生的api。一時心動下載研究。後來發現也並不是想象中多麼神奇的事情。

於是乎自己動手;想用html的方式來做介面設計,用js呼叫一些常用的系統api。比如說http請求、彈窗提示等等。

說搞就搞,由於自己以前沒有怎麼接觸過webview,先做個demo測試測試。

所有程式碼準備就緒。結果一執行點選按鈕居然什麼反應都沒有。

就十幾行程式碼;各種檢查,各種看不出問題所在。

又把以前做的類似的webview的demo匯入eclipse執行。居然沒問題。。。。。。

把兩個demo程式碼反覆比較,都沒有找到問題。

結果最終發現居然是我 target api 是4.2的以前的api是4.0的。。。。

4.2及以上api與JavaScript互動時需要在方法上添加註解@JavascriptInterface 。

好了。下面吧程式碼擺出來做個記錄:


我們需要些的就三個檔案畫紅圈的檔案。

MainActivity.Java

  1. package com.example.testwebview;  
  2. import
     android.os.Bundle;  
  3. import android.annotation.SuppressLint;  
  4. import android.app.Activity;  
  5. import android.webkit.JavascriptInterface;  
  6. import android.webkit.WebView;  
  7. import android.widget.Toast;  
  8. publicclass MainActivity extends Activity {  
  9.     private WebView webView;  
  10.     @SuppressLint("SetJavaScriptEnabled"
    )  
  11.     @Override
  12.     protectedvoid onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.webview);  
  15.         webView = (WebView)this.findViewById(R.id.webview);  
  16.         //啟用javascript
  17.         webView.getSettings().setJavaScriptEnabled(true);  
  18.         //載入本地html檔案
  19.         webView.loadUrl("file:///android_asset/test.html");  
  20.         /** 
  21.          * 新增javascriptInterface 
  22.          * 第一個引數:這裡需要一個與js對映的java物件 
  23.          * 第二個引數:該java物件被對映為js物件後在js裡面的物件名,在js中要呼叫該物件的方法就是通過這個來呼叫 
  24.          */
  25.         webView.addJavascriptInterface(new JSInterface(), "jsi");  
  26.     }  
  27.     @SuppressWarnings("unused")  
  28.     privatefinalclass JSInterface{  
  29.         /** 
  30.          * 注意這裡的@JavascriptInterface註解, target是4.2以上都需要新增這個註解,否則無法呼叫 
  31.          * @param text 
  32.          */
  33.         @JavascriptInterface
  34.         publicvoid showToast(String text){  
  35.             Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();  
  36.         }  
  37.         @JavascriptInterface
  38.         publicvoid showJsText(String text){  
  39.             webView.loadUrl("javascript:jsText('"+text+"')");  
  40.         }  
  41.     }  
  42. }  
test.html
  1. <html>
  2.     <head>
  3.         <metahttp-equiv="content-type"content="text/html;charset=utf-8">
  4.         <title></title>
  5.         <scripttype="text/javascript">
  6.         //這個function是需要被java呼叫的  
  7.         function jsText(text){  
  8.             document.getElementById('ttt').innerHTML=text;  
  9.         }  
  10.         </script>
  11.     </head>
  12.     <body>
  13.         <inputtype="button"onclick="jsi.showToast('測試js呼叫系統api')"value="呼叫系統api Toast"/><br/>
  14.         <inputtype="button"onclick="jsi.showJsText('測試java回撥js')"value="讓java方法回撥html中的js方法"/>
  15.         <divid="ttt"></div>
  16.     </body>
  17. </html>
webview.xml
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <WebViewxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:id="@+id/webview">
  6. </WebView>
關於AndroidManifest.xml中的許可權問題。我看了很多帖子都說要加internet訪問許可權。

其實經過我測試。如果你的應用中沒有需要訪問網路的地方、並且你的所有html js css都是放在assets目錄下沒有從網路上讀取檔案,是可以不加這個許可權的。

下面是我的androidmanifest檔案


到這裡我的測試是完全通過的。