日期:2014-05-16  浏览次数:20323 次

Android 混合了 JSON 的 Android 应用程序
通过WebView在javascript里调用java 方法代码, 在java代码里执行javascript代码, 二者通过json进行数据交换

设置 WebView 小部件

// connect to our browser so we can manipulate it
browser = (WebView) findViewById(R.id.calculator);

// set a webview client to override the default functionality
browser.setWebViewClient(new wvClient());

// get settings so we can config our WebView instance
WebSettings settings = browser.getSettings();

// JavaScript?  Of course!
settings.setJavaScriptEnabled(true);

// clear cache
browser.clearCache(true);

// this is necessary for "alert()" to work
browser.setWebChromeClient(new WebChromeClient());

// add our custom functionality to the javascript environment
browser.addJavascriptInterface(new CalculatorHandler(), "calc");

// uncomment this if you want to use the webview as an invisible calculator!
//browser.setVisibility(View.INVISIBLE);

// load a page to get things started
browser.loadUrl("file:///android_asset/index.html");

// allows the control to receive focus
// on some versions of Android the webview doesn't handle input focus properly
// this seems to make things work with Android 2.1, but not 2.2
// browser.requestFocusFromTouch();



将一个名为 browser 的 Activity 范围变量捆绑到了 WebView 控件。WebView 是一个相当复杂的类,可高度定制。例如,您需要设置几个类,以得到与 web 浏览器相关的预期函数。这是程序员必须投入一定精力来得到一些有用函数的地方之一。但是,此定制是没有限制的。对于此应用程序的目的来说,WebView 控件已经进行了最低限度的部署。

WebViewClient 提供用于捕获各种事件的钩子,这些事件包括页面加载开始和结束、表单重新提交、键盘截取以及程序员喜欢跟踪并操纵的很多其他事件。类似地,您需要 WebChromeClient 的一个实例,用于允许诸如非常有用的 alert() JavaScript 函数之类的函数。使用 WebSettings 来为控件启用 JavaScript。


连接 JavaScript 接口

下一步是启用 Activity 中的 Java 代码,以与 WebView 管理的 HTML 文件中的 JavaScript 代码交互。这是通过调用 addJavascriptInterface() 方法完成的,如 清单 4 所示。

该函数的参数是一个 Java 类的实例和一个名称空间标识符。例如,对于这个应用程序,您定义一个 calc 名称空间,并实现名为 CalculatorHandler 的类中的代码,如 清单 5 所示。

清单 5. CalculatorHandler 实现
// Javascript handler
final class CalculatorHandler
{
    private int iterations = 0;
    // write to LogCat (Info)
    public void Info(String str) {
        iterations++;
        Log.i("Calc",str);
    }
    // write to LogCat (Error)
    public void Error(String str) {
        iterations++;
        Log.e("Calc",str);
    }
    // sample to retrieve a custom - written function with the details provided
    // by the Android native application code
    public String GetSomeFunction()
    {
        iterations++;
        return "var q = 6;function dynamicFunc(v) { return v + q; }";
    }
    // Kill the app
    public void EndApp() {
        iterations++;
        finish();
    }
    public void setAnswer(String a)
    {
        iterations++;
        Log.i(tag,"Answer [" + a + "]");
    }
    public int getIterations()
    {
        return iterations;
    }
    public void SendHistory(String s)
    {
        Log.i("Calc","SendHistory" + s);
        try {
            JSONArray ja = new JSONArray(s);
            for (int i=0;i<ja.length();i++) {
                Log.i("Calc","History entry #" + (i+1) + " is [" + ja.getString(i)+ "]");
            }
        } catch (Exception ee) {
            Log.e("Calc",ee.getMessage());
        }
    }
}

在 JavaScript 环境中,通过 window.calc.methodname 语法访问 CalculatorHandler 的方法。例如,CalculatorHandler 实现一个名为 Info() 的方法,后者接受一个字符串参数并将之写到应用程序日志中。要从 JavaScript 环境访问此方法,可使用类似这样的语法:window.calc.Info("write this string to the application log!");。

基本了解了如何从 JavaScript 代码调用 Java 代码之后,我们再来看 清单 6 中的 index.html 文件,看各种方法是如何被调用的。

清单 6. WebView 控件中呈现(和执行)的 index.html
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=0.25,
    user-scalable=yes" />
<title>Android to JavaScript with JSON</title>
</head>
<script language="JavaScript">
var cmdHistory = new