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呼叫原生是使用 JavaScript:button.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方法了