Android—-WebView與JavaScript交互調用(1)

現在很多的手機應用,都可能會直接嵌入一個web頁面。這樣做的好處:一個是功能更新方便,維護起來容易,隻需要維護服務器的頁面即可,不需要更新客戶端;另一個是功能通用,不僅android可以用,ios也可以用,symbian也可以直接用。而且WebView對Javascript的支持很強,但也沒有親身編程測試一下,所有這裡舉個例子說明一下如何在Javascript中調用java中函數

1、創建一個android 工程 TestWebView

2、繼承自 Activity

[java]
<pre name="code" class="java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-size:16px;">public class TestWebView extends Activity { 
    private WebView mWebView; 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        mWebView = (WebView) findViewById(R.id.htmlview); 
 
        WebSettings webSettings = mWebView.getSettings(); 
         
        // 是否允許在webview中執行javascript  
        webSettings.setJavaScriptEnabled(true); 
 
        // 綁定java對象到JavaScript中,這樣就能在JavaScript中調用java對象,實現通信。  
        // 這種方法第一個參數就是java對象,第二個參數表示java對象的別名,在JavaScript中使用  
         mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo"); 
 
         // webview加載本地html代碼,註意本地html代碼必須放在工程assets目錄下,然後通過  
        // file:///android_asset/demo.html訪問  
        mWebView.loadUrl("file:///android_asset/demo.html"); 
    } 
     
    public class DemoJavaScriptInterface { 
        public DemoJavaScriptInterface() { 
 
        } 
 
        public int mydata() { 
            Log.i("TEST","mydata….."); 
            return 0; 
        } 
    } 
}</span> 
<pre name="code" class="java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-size:16px;">public class TestWebView extends Activity {
 private WebView mWebView;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  mWebView = (WebView) findViewById(R.id.htmlview);

  WebSettings webSettings = mWebView.getSettings();
  
  // 是否允許在webview中執行javascript
  webSettings.setJavaScriptEnabled(true);

  // 綁定java對象到JavaScript中,這樣就能在JavaScript中調用java對象,實現通信。
  // 這種方法第一個參數就是java對象,第二個參數表示java對象的別名,在JavaScript中使用
   mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");

   // webview加載本地html代碼,註意本地html代碼必須放在工程assets目錄下,然後通過
  // file:///android_asset/demo.html訪問
  mWebView.loadUrl("file:///android_asset/demo.html");
 }
 
 public class DemoJavaScriptInterface {
  public DemoJavaScriptInterface() {

  }

  public int mydata() {
   Log.i("TEST","mydata…..");
   return 0;
  }
 }
}</span>

3、修改 main.xml 文件如下

[html]
<span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    > 
 
    <WebView android:id="@+id/htmlview" 
        android:layout_centerHorizontal="true" android:layout_centerVertical="true" 
        android:layout_marginLeft="0px" android:layout_width="fill_parent" 
        android:layout_height="fill_parent" /> 
 
</RelativeLayout></span> 
<span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent" android:layout_height="fill_parent"
 >

 <WebView android:id="@+id/htmlview"
  android:layout_centerHorizontal="true" android:layout_centerVertical="true"
  android:layout_marginLeft="0px" android:layout_width="fill_parent"
  android:layout_height="fill_parent" />

</RelativeLayout></span>
4、在assets目錄下,新建一個html文件:demo.html,使用JAVAScript代碼編寫

[javascript]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>Insert title here</title>  
</head>  
    <body>this is web html 
    <p id="output" >test</p> 
        <input type="submit" value="buttons"  
        onclick="document.getElementById('output').innerHTML=window.demo.mydata()"/>  
    </body>  
</html> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
    <body>this is web html
    <p id="output" >test</p>
        <input type="submit" value="buttons"
        onclick="document.getElementById('output').innerHTML=window.demo.mydata()"/>
    </body>
</html>

註意上面 [javascript] view plaincopyprint?
onclick="document.getElementById('output').innerHTML=window.demo.mydata()" 
onclick="document.getElementById('output').innerHTML=window.demo.mydata()"

直接調用 window.demo.mydata() 的方法

 

ok, 輕松就將代碼寫完,現在補充說明一下用到的知識點:

先看SDK API函數介紹:

public void addJavascriptInterface (Object obj, String interfaceName)

Use this function to bind an object to JavaScript so that the methods can be accessed from JavaScript.

IMPORTANT:

Using addJavascriptInterface() allows JavaScript to control your application. This can be a very useful feature or a dangerous security issue. When the HTML in the WebView is untrustworthy (for example, part or all of the HTML is provided by some person or process), then an attacker could inject HTML that will execute your code and possibly any code of the attacker's choosing.
Do not use addJavascriptInterface() unless all of the HTML in this WebView was written by you.
The Java object that is bound runs in another thread and not in the thread that it was constructed in.

Parameters
obj The class instance to bind to JavaScript, null instances are ignored.
interfaceName The name to used to expose the instance in JavaScript.

 

通過addJavascriptInterface(Object obj,String interfaceName)這個方法,該方法將一個java對象綁定到一個javascript對象中,javascript對象名就是 interfaceName(demo),作用域是Global。這樣初始化webview後,在webview加載的頁面中就可以直接通過 javascript:window.demo訪問到綁定的java對象瞭。

 

再補充下在開發過程中應該註意幾點:

1、AndroidManifest.xml中必須使用許可"android.permission.INTERNET",否則會出Web page not available錯誤

2、如果訪問的頁面中有Javascript,則webview必須設置支持Javascript。
webview.getSettings().setJavaScriptEnabled(true);

3、如果頁面中鏈接,如果希望點擊鏈接繼續在當前browser中響應,而不是新開Android的系統browser中響應該鏈接,必須覆蓋webview的WebViewClient對象。

mWebView.setWebViewClient(new WebViewClient(){

[java]
<span style="font-size:16px;">            @Override 
            public boolean shouldOverrideUrlLoading(WebView view, String url) { 
                view.loadUrl(url);  
                return true; 
            } 
        });</span> 
<span style="font-size:16px;">   @Override
   public boolean shouldOverrideUrlLoading(WebView view, String url) {
    view.loadUrl(url);
    return true;
   }
  });</span>

4、如果不做任何處理,瀏覽網頁,點擊系統“Back”鍵,整個Browser會調用finish()而結束自身,如果希望瀏覽的網頁回退而不是推出瀏覽器,需要在當前Activity中處理並消費掉該Back事件。

[java]
<pre name="code" class="java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "></span><pre name="code" class="java">   @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { 
            mWebView.goBack(); 
            return true; 
        } 
        return super.onKeyDown(keyCode, event); 
    } 
<pre name="code" class="java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "></span><pre name="code" class="java"> @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
   mWebView.goBack();
   return true;
  }
  return super.onKeyDown(keyCode, event);
 }
5、addJavascriptInterface方法中要綁定的Java對象及方法要運行另外的線程中,不能運行在構造他的線程中,這也是使用Handler的目的。如此上面的代碼則可以修改成如下即可,利用Handler發送消息進行處理:
[java]
<span style="color:rgb(75,78,81); line-height:25px"><span style="font-size:16px"></span></span><pre name="code" class="java">        public int mydata() { 
        mHandler.post(new Runnable() { 
            public void run() { 
                Log.i("TEST", "mydata….."); 
            } 
        }); 
        return 0; 
    } 

 

 

摘自 andyhuabing的專欄

發佈留言