當我們去開發一個基於web的android app時,我們第一需要處理的就是與JavaScript的交互問題,Android需要做的事情就是開放某些特定的接口供web裏的JavaScript調用,可以開放彈出框功能,Toast,界面跳轉等等,這樣我們的web視圖以假亂真的當成Android的原生界面,而這套web代碼又可以嵌入iPhone的客戶端中,也就是說Android和IOS客戶端僅僅是提供一個共web使用的框架,業務都由web端處理,這豈不是開發一次,可處處運行。然而這一切都是後話,且讓我們先實現WebView和JavaScript的交互問題。這裏我以Android
app爲例。
1. 首先在Eclipse中創建一個空的Android項目,我將它命名爲JSInteraction,找到並打開AndroidManifest.xml文件,在Permissions裏添加一個android.permission.WRITE_EXTERNAL_STORAGE權限。
2.這裏我已經添加了一個主頁面activity_main.xml,一個主要的Activity MainActivity.java,及一個提供各種功能供JavaScript調用的類JsOperator.java。
主要的目錄結構如下圖所示
主頁面activity_main.xml代碼如下所示,僅僅只有一個WebView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java的代碼如下所示,表示添加供JS調用的對象,其別名是JsInteraction,這樣在JS中只要寫JsInteraction.<方法名稱>()就可以調用相應的方法了。WebView將加載assets文件夾裏LoginJs文件夾下的login.html,這個文件會在後面創建。
package com.yld.jsinteraction;
import android.support.v7.app.ActionBarActivity;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.annotation.SuppressLint;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.webView = (WebView) this.findViewById(R.id.webView);
this.initializeWebView();
}
@SuppressLint({ "NewApi", "SetJavaScriptEnabled" })
private void initializeWebView(){
webView.addJavascriptInterface(new JsOperator(MainActivity.this),
"JsInteraction");
try {
String url = "file:///android_asset/LoginJs/login.html";
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
this.webView.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
JsOperator.java的代碼如下
package com.yld.jsinteraction;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.webkit.JavascriptInterface;
public class JsOperator {
private Context context;
public JsOperator(Context context) {
this.context = context;
}
/**
* 彈出消息對話框
*/
@JavascriptInterface
public void showDialog(String message) {
AlertDialog.Builder builder = new Builder(context);
builder.setMessage(message);
builder.setTitle("提示");
builder.setPositiveButton("確認", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
/**
* 獲取登錄的用戶名和密碼
* @return JSON格式的字符串
*/
@JavascriptInterface
public String getLoginInfo(){
try{
JSONObject login = new JSONObject();
login.put("Username", "YLD");
login.put("Password", "111");
return login.toString();
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
JsOperator提供了兩個方法,一個方法用來彈出對話框,另一個方法則是返回一個登錄信息的JSON字符串,而且這兩個方法都打上了標籤@JavascriptInterface,這是比較重要的,因爲在較低的版本中如果不聲明它是JavaScript可調用的方法,JS將無法調用。
3.在assets文件夾下創建LoginJs文件夾,並在其下創建兩個文件login.html,login.js
login.html中有一個用戶名密碼輸入框及一個登錄按鈕,代碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title id="title">Login</title>
<script type="text/javascript" src="login.js"></script>
</head>
<body style="background:lightblue">
<div style="margin-top: 20px;margin-left: 20px">
<div>
<label>Username:</label>
<input id="txtUsername" type="text" style="margin-left: 20px"/>
</div>
<div style="margin-top: 20px">
<label>Password:</label>
<input id="txtPassword" type="text" style="margin-left: 20px"/>
</div>
<div style="margin-top: 20px;margin-left: 160px">
<button onclick="loginObj.login()" style="width:100px">Login</button>
</div>
</div>
</body>
</html>
在login.js的setLoginInfo裏使用JsInteraction.getLoginInfo()調用android提供的接口,並獲取登錄信息並將登錄信息填充到用戶輸入框中,login方法則是調用了JsInteraction.showDialog("Login start...")來調用android端提供的彈出對話框的接口。
var Login = (function(){
function Login(){
}
Login.prototype.login = function(){
JsInteraction.showDialog("Login start...");
}
Login.prototype.setLoginInfo = function(){
var logininfoJson = JsInteraction.getLoginInfo();
//解析json字符串
var logininfo = eval("("+logininfoJson+")");
document.getElementById("txtUsername").value = logininfo.Username;
document.getElementById("txtPassword").value = logininfo.Password;
}
return Login;
})();
var loginObj = new Login();
window.onload=function(){
loginObj.setLoginInfo();
}
4.Html和客戶端的創建已經完成,運行效果如下
點擊Login按鈕
源代碼下載頁:http://download.csdn.net/detail/leyyang/8995887