当下HTML5非常火,使用HTML5混合开发的好处是当开发者想要修改某一个非原生页面时,修改提交之后不用对应用进行升级发版,有人说HTML5将来将会取代原生开发,但个人感觉就目前来说这体验感还没完全达到原生的水平,今天做了个小Demo用于android与javaScript的交互测试
1. 说混合开发,其实说白了就是一个webView去加载网页,当然对webview进行各种配置,以及javaScript交互的配置。先说说配置WebView吧
webView.setWebChromeClient(_chromeClient);
webView.setWebViewClient(_client);
//_plugin为与JS交互的插件类,H5Plugin为JS中的调用原生方法的插件名称
webView.addJavascriptInterface(_plugin, "H5Plugin");
// 设置浏览器属性
settings = webView.getSettings();
settings.setDefaultTextEncodingName("utf-8"); // 默认编码
settings.setJavaScriptEnabled(true); // JS 交互
settings.setLoadsImagesAutomatically(true);//设置自动加载图片
settings.setUseWideViewPort(true);//可任意比例缩放
settings.setLoadWithOverviewMode(true);
settings.setAllowFileAccessFromFileURLs(true);
// 缓存设置
String cacheDir = this.getCacheDir().getAbsolutePath();
settings.setAppCachePath(cacheDir);
settings.setAppCacheEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowContentAccess(true);
settings.setAllowFileAccess(true);
// 数据库设置
settings.setDatabaseEnabled(true);
if (android.os.Build.VERSION.SDK_INT < 18) {
settings.setDatabasePath(cacheDir);
}
// 定位设置
settings.setGeolocationEnabled(true);
settings.setGeolocationDatabasePath(cacheDir);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
webView.setLongClickable(false);
webView.requestFocusFromTouch();
//判断网络连接状态下的不同缓存设置
if (isNetworkConnected(context)) {
//根据cache-control决定是否从网络上取数据
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
//只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
2.webView的5中缓存模式:
缓存模式(5种)
LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
总结:根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络 时,使用LOAD_CACHE_ELSE_NETWORK。
3.用于jS和原生交互的插件类:
public class H5Plugin {
private Activity activity;
public H5Plugin(Activity activity) {
this.activity = activity;
}
//4.4版本以上,本地方法要加上注解@JavascriptInterface,否则会找不到方法。
@JavascriptInterface
public void showToast(String toastMsg) {
Log.i("H5Plugin", "toastMsg:"+toastMsg);
if(!TextUtils.isEmpty(toastMsg)){
Toast.makeText(activity, toastMsg, Toast.LENGTH_SHORT).show();
}
}
@JavascriptInterface
public void newACtivity() {
Log.i("H5Plugin", "newActivity");
activity.startActivity(new Intent(activity,TextActivity.class));
}
}
4.JavaScript中原生方法的调用:
在js中直接可以用过插件类的类名直接调用其方法,如果出现调用错误或者是提示未定义的情况,请注意JS中插件类的名字以及方法名是否和原生端代码一致,还有调用的方法在Android 4.4之后需要加上加上注解@JavascriptInterface js端代码示例如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script>
//测试原生端Toast 原生端方法名:newACtivity();
var checkToast = function () {
try {
H5Plugin.showToast("这是JS回调的Message");
} catch (e) {
alert(e.message)
}
}
//测试原生端Intent,原生端方法名:newACtivity();
var checkIntent = function () {
try {
H5Plugin.newACtivity();
} catch (e) {
alert(e.message)
}
}
</script>
<style>
#btn1 {
width:500px;
height:100px;
font-size:25px;
align-content:center;
}
</style>
</head>
<body>
<hr/>
<div>
<br>
<input id="btn1" type="button" value="JS调用原生Toast" onclick="checkToast()"/>
</div>
<div>
<br>
<input id="btn1" type="button" value="JS调用原生Intent" onclick="checkIntent()" />
</div>
</body>
</html>
5.图片示例:
![这里写图片描述]()
参考:>