1. 程式人生 > >android與H5混合開發

android與H5混合開發

最近在左一個Android原生的H5混合開發的APP,之前還沒有好好的總結一下Android原生 和 H5 之間互動的方法,這裡來總結一下:

1、hybrid通訊,主要就是前端的js和我們Android端的通訊     這是最基本JS和Java 的通訊方式:
       這裡我們分四塊來講:  

      (1)、js呼叫android原生的程式碼(不傳遞引數)

      (2)、js呼叫android原生的程式碼(傳遞引數)

      (3)、android原生呼叫JS的程式碼(不傳遞引數)

      (4)、android原生呼叫JS的程式碼(傳遞引數)

    
     好的我們這裡先來建立一個工程:

    在工程的main資料夾下建立一個資料夾assets ,然後把寫好的H5頁面放入該資料夾中,H5頁面程式碼如下:

  <pre name="code" class="html"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    <title>這裡是一個H5頁面</title>  
</head>  
  
<body>  
<p id="ptext">點選按鍵0 執行android中的 public void click0(){} 方法</p>  
<Button id="buttonId0" class="buttonClass" onclick="javascript:button.click0()">按鍵0</Button>  
<p>點選按鍵1 執行android中的 public void click0(String data1,String data2){}方法</p>  
<Button id="buttonId1" class="buttonClass" onclick="javascript:button.click0('引數1','引數2')">按鍵1</Button>  
  
<script>  
        function setRed(){  
        //這個方法設定 id 為 ptext 的元素的背景色為紅色  
        var a = document.getElementById('ptext');  
        a.style.backgroundColor="#F00";  
    }  
    function setColor(color,text){  
        //這個方法設定 id 為 ptext 的元素的背景色為指定顏色  
        //設定 id 為 ptext 的元素的內容為text  
        var a = document.getElementById('ptext');  
        a.style.backgroundColor=color;  
        a.innerHTML = text;  
    }  
    </script>  
</body>  



上邊是一個簡單的H5頁面,其中包含連個按鈕,點選按鈕觸發android 原生的方法;裡邊還有兩個JS 方法,其中包括兩個,主要用於給android原生去呼叫。

回到 activity_main.xml中,佈局如下:

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="manyizilin.com.androidh5.MainActivity">  
  
    <WebView android:id="@+id/webview"  
        android:layout_height="match_parent"  
        android:layout_width="match_parent"  
        />  
    <LinearLayout android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:orientation="horizontal">  
        <Button android:id="@+id/red"  
            android:layout_height="wrap_content"  
            android:layout_width="wrap_content"  
            android:layout_weight="1"  
            android:text="背景變成紅色"/>  
        <Button android:id="@+id/color"  
            android:layout_height="wrap_content"  
            android:layout_width="wrap_content"  
            android:layout_weight="1"  
            android:text="背景色可以自定義"/>  
    </LinearLayout>  
</RelativeLayout>  

主要包含一個WebView控制元件和兩個按鈕,點選按鈕可以觸發上邊H5頁面中的JS方法

最後看一下MainActivity的程式碼:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{  
  
    private WebView webView;  
    private Button redButton,colorButton;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        webView = (WebView)findViewById(R.id.webview);  
        redButton = (Button)findViewById(R.id.red);  
        colorButton = (Button)findViewById(R.id.color);  
        redButton.setOnClickListener(this);  
        colorButton.setOnClickListener(this);  
        initWebView();  
        webView.loadUrl("file:///android_asset/android&h5Text0.html"); //載入assets檔案中的H5頁面  
    }  
  
    /** 
     *初始化WebView 
     */  
  @SuppressLint("JavascriptInterface")  //新增該欄位  
 private void initWebView(){  
        WebSettings settings =  webView.getSettings();  
        settings.setJavaScriptEnabled(true);  //設定執行使用JS  
        ButtonClick click = new ButtonClick();  
        //這裡新增JS的互動事件,這樣H5就可以呼叫原生的程式碼  
        webView.addJavascriptInterface(click,click.toString());  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()){  
            case R.id.red:  //呼叫JS中的無引數方法  
                webView.loadUrl("javascript:setRed()");  
                break;  
            case R.id.color://呼叫JS中的有引數方法  
                webView.loadUrl("javascript:setColor('#00f','這是android 原生呼叫JS程式碼的觸發事件')");  
                break;  
        }  
    }  
  
    /** 
     * H5頁面按鈕點選觸發事件 
     */  
    class ButtonClick{  
  
        //這是 button.click0() 的觸發事件  
        //H5呼叫方法:javascript:button.click0()  
        @JavascriptInterface  
        public void click0(){  
           show("title","");  
        }  
  
        //這是 button.click0() 的觸發事件,可以傳遞待引數  
        //H5呼叫方法:javascript:button.click0('引數1','引數2')  
        @JavascriptInterface  
        public void click0(String data1,String data2){  
            show(data1,data2);  
        }  
  
  
        @JavascriptInterface  //必須新增,這樣才可以標誌這個類的名稱是 button  
        public String toString(){  
            return "button";  
        }  
  
        private void show(String title,String data){  
            new AlertDialog.Builder(getWindow().getContext())  
                    .setTitle(title)  
                    .setMessage(data)  
                    .setPositiveButton("確定",null)  
                    .create().show();  
        }  
    }  
}  


好了上邊的程式碼就是這樣,接下來我們來詳細解釋一下:

首先我們拿到了一個WebView,初始化webView,在webView中想要執行JS指令碼,必須要設定:

WebSettings settings =  webView.getSettings();
settings.setJavaScriptEnabled(true);  //設定執行使

載入 assets中的H5頁面:

webView.loadUrl("file:///android_asset/android&h5Text0.html"); //載入assets檔案中的H5頁面


接下來寫一個類,專門用於JS呼叫;

     記得必須寫  寫toString() 方法,放回來的結果和 JS中呼叫的方法的類名一致:

  比如:在這個例子中JS呼叫原生是使用 JavaScriptbutton.click0();   注意一下,這個的 button 和Java中響應的類的toSring() 方法的返回值是一樣的。

@JavascriptInterface 

         public String toString(){        return "button";         }

JavaScript:button.click0();  其中的 click0 和java響應類的觸發方法的方法名是一致的。方法的許可權都是 public 。

**  
     * H5頁面按鈕點選觸發事件  
     */  
    class ButtonClick{  
  
        //這是 button.click0() 的觸發事件  
        //H5呼叫方法:javascript:button.click0()  
        @JavascriptInterface  
        public void click0(){  
           show("title","");  
        }  
  
        //這是 button.click0() 的觸發事件,可以傳遞待引數  
        //H5呼叫方法:javascript:button.click0('引數1','引數2')  
        @JavascriptInterface  
        public void click0(String data1,String data2){  
            show(data1,data2);  
        }  
  
  
        @JavascriptInterface  //必須新增,這樣才可以標誌這個類的名稱是 button //在android 4.2之前不需要新增,在4.2之後需要新增  
        public String toString(){  
            return "<strong>button</strong>";  
        }  
  
        private void show(String title,String data){  
            new AlertDialog.Builder(getWindow().getContext())  
                    .setTitle(title)  
                    .setMessage(data)  
                    .setPositiveButton("確定",null)  
                    .create().show();  
        }  
    }  

好了,準備得差不多了

  (1)、js呼叫android原生的程式碼(不傳遞引數)/   (2)、js呼叫android原生的程式碼(傳遞引數)

     然後通過WebView的addJavascriptInterface方法去注入一個我們自己寫的interface。

   ButtonClick click = new ButtonClick();   
  //這裡新增JS的互動事件,這樣H5就可以呼叫原生的程式碼  
  webView.addJavascriptInterface(click,click.toString());

    這裡來說明一下 addJavascriptInterface 這個方法,前一個引數是觸發的物件,後一個引數是這物件的標誌,需要在這個類的內部新增下面的程式碼,這樣JS才可以識別這個類的內部方法:

@JavascriptInterface  //@JavascriptInterface必須新增,這樣才可以標誌這個類的名稱是 button //在android 4.2之前不需要新增,在4.2之後需要新增  
  public String toString(){  
      return "button";  
  } 

   現在點選H5頁面中的 按鍵0 就可以觸發事件  ButtonClick 類中的 click0() 方法了,點選  按鍵1  就可以觸發事 ButtonClick 類中的 click0(String data1,String data2) 方法了

    (3)、android原生呼叫JS的程式碼(不傳遞引數)

       在載入 H5頁面結束後,呼叫   webView.loadUrl("javascript:setRed()");  那麼就可以呼叫 該頁面中的 setRed() 這個JS方法了

   (4)、android原生呼叫JS的程式碼(傳遞引數)

   在載入 H5頁面結束後,呼叫 

 webView.loadUrl("javascript:setColor('#00f','這是android 原生呼叫JS程式碼的觸發事件')");  

那麼就可以呼叫 該頁面中的 setColor(color,text)  這個JS方法了