標籤:
在WebView中不僅可以運行HTML代碼,更重要的是,WebView可以與Javascript互相調用。也就是說,在Javascript中可以擷取WebView的內容,與此同時,在WebView中也可以調用Javascript裡面的方法。
下面通過如下案例來分析WebView與javascript的互動
1.第一步在布局檔案中聲明WebView(activity_main.xml)
<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="${relativePackage}.${activityClass}" > <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>
2.在項目的assets目錄下面存放html檔案(user.html)
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><script type="text/javascript"> function show(jsondata){ //通過eval函數 轉化成 josn對象var jsonobjs = eval(jsondata);var table = document.getElementById("user");for(var y=0; y<jsonobjs.length; y++){ var tr = table.insertRow(table.rows.length); //添加一行 //添加三列 var td1 = tr.insertCell(0); var td2 = tr.insertCell(1); td2.align = "center"; var td3 = tr.insertCell(2); //設定列內容和屬性 td1.innerHTML = jsonobjs[y].id; td2.innerHTML = "<a href='javascript:csdn.call("+jsonobjs[y].phone+")'>"+ jsonobjs[y].name + "</a>"; td3.innerHTML = jsonobjs[y].phone;}}//警告框function alertMsg(){ alert("hello alert");}//確認框function confirmMsg(){ confirm("hello confirm");}//提示框function promptMsg(){ prompt("hello prompt");} </script></head><body onload="javascript:csdn.userList()"><table border="0" width="100%" id="user"><tr><td width="20%">序號</td><td align="center">姓名</td><td width="20%">電話</td></tr></table><div> <input type="button" onclick="javascript:alertMsg()" value="彈出警告框"/> <input type="button" onclick="javascript:confirmMsg()" value="確認框"/> <input type="button" onclick="javascript:promptMsg()" value="提示框"/></div></body></html>
備忘:為了讓WebView從apk檔案中載入 assets,Android SDK提供了一個schema,首碼為"file:///android_asset/"。WebView遇到這樣的schema,就去當前包中的 assets目錄中找內容
3.具體代碼的實現(詳解見代碼注釋)
public class MainActivity extends Activity {// 聲明控制項對象private WebView webView;// 聲明handler對象private Handler handler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 擷取控制項對象webView = (WebView) findViewById(R.id.webView1);// 擷取webview控制項屬性對象WebSettings webSettings = webView.getSettings();// 支援javascript代碼webSettings.setJavaScriptEnabled(true);// 添加javascript介面對象webView.addJavascriptInterface(new JavascriptUser(), "csdn");// WebChromeClient主要用來輔助WebView處理Javascript的對話方塊、網站表徵圖、網站標題以及網頁載入進度等。webView.setWebChromeClient(new WebChromeClient() {//處理確認框@Overridepublic boolean onJsConfirm(WebView view, String url,String message, final JsResult result) {// 建立builder對象new AlertDialog.Builder(MainActivity.this).setTitle("onJsConfirm").setMessage(message).setPositiveButton("確認", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {result.cancel();//如果不取消,按鈕只能處理一次,取消後不限制}}).show();return true;}//處理提示框@Overridepublic boolean onJsPrompt(WebView view, String url, String message,String defaultValue, final JsPromptResult result) {// 建立builder對象new AlertDialog.Builder(MainActivity.this).setTitle("onJsPrompt").setMessage(message).setPositiveButton("確認", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {result.cancel();}}).show();return true;}//處理警告框@Overridepublic boolean onJsAlert(WebView view, String url, String message,final JsResult result) {/* * Toast.makeText(MainActivity.this, message, 1).show(); * * result.confirm(); //確認後,可以處理多次點擊,否則按鈕只能點擊一次 */// 建立builder對象new AlertDialog.Builder(MainActivity.this).setTitle("onJsAlert").setMessage(message).setPositiveButton("確認", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {result.cancel();}}).show();return true;}});// 載入顯示的網頁 規定:schema file:///android_assetwebView.loadUrl("file:///android_asset/user.html");}class JavascriptUser {// 打電話 備忘:在android17版本之後必須通過 @JavascriptInterface 註解實現,否則會出現bug(詳見異常)//這個方法是在網頁中調用的:<a href='javascript:csdn.call("+jsonobjs[y].phone+")'>"+ jsonobjs[y].name + "</a>@JavascriptInterfacepublic void call(final String phone) {//處理的操作要在hanlder中處理handler.post(new Runnable() {@Overridepublic void run() {//這裡要實現打電話的操作,必須添加打電話的許可權 <uses-permission android:name="android.permission.CALL_PHONE"/>startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone)));}});}//載入所有的資料 備忘:在android 17版本之後必須通過 @JavascriptInterface 註解實現,//否則會出現"Uncaught TypeError: Object [object Object] has no method 'userList'", //source: file:///android_asset/user.html (31) //這個方法是在網頁中調用的onload="javascript:csdn.userList()"@JavascriptInterfacepublic void userList() {handler.post(new Runnable() {@Overridepublic void run() {try {// 建立json對象JSONObject jsonObject = new JSONObject();jsonObject.put("id", 1);jsonObject.put("name", "chenhj");jsonObject.put("phone", "110");// 建立json對象JSONObject jsonObject2 = new JSONObject();jsonObject2.put("id", 2);jsonObject2.put("name", "wangsan");jsonObject2.put("phone", "112");// 建立json數組JSONArray jsonArray = new JSONArray();jsonArray.put(jsonObject);jsonArray.put(jsonObject2);// 把json數群組轉換成字串String jsonstr = jsonArray.toString();// TODO Auto-generated method stub// 調用網頁中的javascript中的show函數webView.loadUrl("javascript:show('" + jsonstr + "')");} catch (JSONException e) {e.printStackTrace();}}});}}}
4.運行說明:
4.1當成功部署,啟動後的介面如下(備忘:網頁中調用的onload="javascript:csdn.userList()" 與java代碼中調用了webView.loadUrl("javascript:show(‘" + jsonstr + "‘)");
4.2當點擊使用者名稱比如chj時 會進入到撥號介面;說明成功調用了java中的call方法
4.3當點擊彈出警告框 按鈕時 會出現如下介面;說明成功調用了WebChromeClient子類中重寫的onJsAlert
4.4當點擊 確認框 按鈕時 會出現如下介面;說明成功調用了WebChromeClient子類中重寫的onJsConfirm
4.5當點擊提示框 按鈕 會出現如下介面;說明成功調用了WebChromeClient子類中重寫的onJsPrompt
16_android_WebView與Javascript的互動