Board logo

标题: 灵活高效的在 Android Native App 开发中显示 HTML 内容(1) [打印本页]

作者: look_w    时间: 2018-11-2 16:16     标题: 灵活高效的在 Android Native App 开发中显示 HTML 内容(1)

其中使用最多的两种方式分别为:
虽然这两种方式都可以显示 HTML 内容,但是其对用户交互的响应方式却有较大的不同。本文通过两个实例来说明:1) 这两种方式的基本使用方式。2) 这两种方式的交互如何实现。3) 通过对比阐述这两种方式各适合于哪些应用场景。
背景对于有显示 HTML 内容的 Android 应用来说,使用 Android SDK WebView 来显示是最简单的方式,但是并不是所有的场景下都适合使用 WebView 来显示 HTML 内容,例如,如果应用要显示的内容只是一部分 HTML 片段,就可以利用 TextView 来进行显示,并且效率较高。
另外,使用 WebView 或者 TextView 来显示 HTML 内容,其交互的实现方式有较大的区别,以在 HTML 内容中的图片点击事件为例,在 WebView 模式下,开发人员需要通过注入 JavaScript 代码来进行点击事件的响应,Android 系统提供了 WebView 中 JavaScript 网页脚本调用 Java 类方法的机制;而在 TextView 中,图片会被解析为 ImageSpan,通过在 ImageSpan 上注册点击事件来响应。 本文后两节分别通过实例来讲述这两种方式的使用方法,以及其用户交互方式。
通过 WebView 显示 HTML 内容及用户交互Android 中的 WebView 组件经常用来加载类似 HTML 这样的格式化文本,它强大的注入功能能轻易实现 JavaScript 代码与 Java 代码之间的交互。本文通过一个详细的例子一步一步教你学会使用并理解 WebView。
在 WebView 中显示 HTML 内容Android 的 WebView 组件使用非常简单,可以使用 loadUrl()加载一个 URL 地址,也可以使用 loadData()或 loadDataWithBaseURL()加载一段 HTML 代码片段。loadData()不能加载图片内容,所以在本例中选择使用可以加载图片内容,并获得更强大 Web 支持的 loadDataWithBaseURL()来显示文字与图片内容,如 中所示。
清单 1. loadDataWithBaseURL()方法定义
1
2
3
4
5
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
  checkThread();
  if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
  }




用户交互事件的添加对 loadDataWithBaseURL()方法传入参数前,对参数 data 字符串做处理:
1
2
String data = webContentHandle(DataUtil.getFromAssets(this, "htmlsample/sample.html"));
webview.loadDataWithBaseURL(BASE_PATH + "htmlsample/", data,"text/html", "utf-8", null);




在 webContentHandle()方法中为 HTML 内容增加 JavaScript 代码以实现两张图片分别添加 HTML 的 onclick 事件,并使图片能够全屏显示,还支持按键退出全屏显示。
本例在实现图片点击后全屏显示时,使用了两种方法,分别作用于两张图片。
第一张图片响应点击,会创建新的 Activity 来全屏显示图片(跳出 WebView,JavaScript 调用 Java),按退出键则退出全屏显示(Java 方法)。
第二张图片响应点击,利用纯 HTML 技术实现全屏显示(未跳出 WebView),按退出键退出全屏显示(Java 调用 JavaScript)。
JavaScript 调用 Java
清单 2. JavaScriptInterface 类定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class JavaScriptInterface {
    ......
    @JavascriptInterface
    public void closeApp() {
    activity.finish();
    }   
    @JavascriptInterface
    public void showImage(final String imagePath) {
    Intent i = new Intent(activity, ImageActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString(IMAGE_PATH_KEY, imagePath);
    i.putExtras(bundle);
    activity.startActivity(i);
    }
}




所有被 JavaScript 代码调用的 Java 方法都必须被预定义在一个类里如  所示,本例有两个被调用的方法即 closeApp()和 showImage(),被调用的方法可以带参也可以不带参,值得注意的是参数类型单一。
1
2
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new JavaScriptInterface(this),"JSInterface");




要实现 WebView 与 JavaScript 的交互必须先打开 WebView 对 JavaScript 的支持功能。JavaScript 调用 Java 是通过 addJavascriptInterface()方法来实现的,该方法的第一个参数是一个包含被 JavaScript 代码调用的 Java 方法的对象,本例中就是类 JavaScriptInterface 的实例,第二个参数是该对象在 JavaScript 代码中的变量名,注意该变量是位于全局即 window 下的,即可以在 JavaScript 代码中用"window.变量名.方法名"来调用第一个参数中的方法。对于不带参的 Java 方法调用很简单如 closeApp(),但是对于带参的方法如上面的 showImage(),要注意的是参数的拼接,易拼错,且不易检查,详见代码中的 webContentHandle()方法。
Java 调用 JavaScript
清单 3. 对按返回键的处理
1
2
3
4
5
6
7
8
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
    webview.loadUrl("javascript: window.backAction();");
    return true;
}
return super.onKeyDown(keyCode, event);
}




Java 调用 JavaScript 用的是 WebView 的 loadUrl()方法,该方法不仅能以最常见的 HTTP 地址作为参数,还可以是 JavaScript 代码。 中方法使得用户一旦按下退出键,就会通知 WebView 容器去触发 JavaScript 代码 window.backAction()的执行。
原始 HTML 文本仅仅是文字加两张图片,没有任何点击事件,经过增加 JavaScript 交互处理后图片有了点击事件,并且还能响应设备上的退出键。
在本例中第一张图片用户交互式体验效果如下 。
在本例中第二张图片用户交互式体验效果如下 。
图 1图 2




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0