WebResourceResponse response = null;
// 检查该资源是否已经提前下载完成。我采用的策略是在应用启动时,用户在 wifi 的网络环境下 // 提前下载 H5 页面需要的资源。
boolean resDown = JSHelper.isURLDownValid(url);
if (resDown) {
jsStr = JsjjJSHelper.getResInputStream(url);
if (url.endsWith(".png")) {
response = getWebResourceResponse(url, “image/png”, “.png”);
} else if (url.endsWith(".gif")) {
response = getWebResourceResponse(url, “image/gif”, “.gif”);
} else if (url.endsWith(".jpg")) {
response = getWebResourceResponse(url, “image/jepg”, “.jpg”);
} else if (url.endsWith(".jepg")) {
response = getWebResourceResponse(url, “image/jepg”, “.jepg”);
} else if (url.endsWith(".js") && jsStr != null) {
response = getWebResourceResponse(“text/javascript”, “UTF-8”, “.js”);
} else if (url.endsWith(".css") && jsStr != null) {
response = getWebResourceResponse(“text/css”, “UTF-8”, “.css”);
} else if (url.endsWith(".html") && jsStr != null) {
response = getWebResourceResponse(“text/html”, “UTF-8”, “.html”);
}
}
// 若 response 返回为 null , WebView 会自行请求网络加载资源。
return response;
}
});
private WebResourceResponse getWebResourceResponse(String url, String mime, String style) {
WebResourceResponse response = null;
try {
response = new WebResourceResponse(mime, “UTF-8”, new FileInputStream(new File(getJSPath() + TPMD5.md5String(url) + style)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return response;
}
public String getJsjjJSPath() {
String splashTargetPath = JarEnv.sApplicationContext.getFilesDir().getPath() + “/JS”;
if (!TPFileSysUtil.isDirFileExist(splashTargetPath)) {
TPFileSysUtil.createDir(splashTargetPath);
}
return splashTargetPath + “/”;
}
**
*1:常用 JS 本地化及延迟加载***
**
**资源等文件(不需要更新)本地存储,在需要的时候直接从本地获取。哪些资源需要我们去存储在本地呢,当然是一些不会被更新的资源,例如图片文件,js文件,css文件,比预加载更粗暴的优化方法是直接将常用的 JS 脚本本地化,直接打包放入 apk 中。比如 H5 页面获取用户信息,设置标题等通用方法,就可以直接写入一个 JS 文件,放入 asserts 文件夹,在 WebView 调用了onPageFinished() 方法后进行加载。需要注意的是,在该 JS 文件中需要写入一个 JS 文件载入完毕的事件,这样前端才能接受都爱 JS 文件已经种植完毕,可以调用 JS 中的方法了。 附上一段本地化的 JS 代码。
javascript: ;
(function() {
try{
window.JSBridge = {
‘invoke’: function(name) {
var args = [].slice.call(arguments, 1),
callback = args.pop(),
params, obj = this[name];
if (typeof callback !== ‘function’) {
params = callback;
callback = function() {}
} else {
params = args[0]
} if (typeof obj !== ‘object’ || typeof obj.func !== ‘function’) {
callback({
‘err_msg’: ‘system:function_not_exist’
});
return
}
obj.callback = callback;
obj.params = params;
obj.func(params)
},
‘on’: function(event, callback) {
var obj = this[‘on’ + event];
if (typeof obj !== ‘object’) {
callback({
‘err_msg’: ‘system:function_not_exist’
});
retrun
}
if (typeof callback !== ‘undefined’) obj.callback = callback
},
‘login’: {
‘func’: function(params) {
prompt(“login”, JSON.stringify(params))
},
‘params’: {},
‘callback’: function(res) {}
},
‘settitle’: {
‘func’: function(params) {
prompt(“settitle”,JSON.stringify(params))
},
‘params’: {},
‘callback’: function(res) {}
},
}catch(e){
alert(‘demo.js error:’+e);
}
var readyEvent = document.createEvent(‘Events’);
readyEvent.initEvent(‘JSBridgeReady’, true, true);
document.dispatchEvent(readyEvent)
})();
关于 JS 延迟加载
Android 的 OnPageFinished 事件会在 Javascript 脚本执行完成之后才会触发。如果在页面中使 用JQuery,会在处理完 DOM 对象,执行完 $(document).ready(function() {}); 事件自会后才会渲染并显示页面。而同样的页面在 iPhone 上却是载入相当的快,因为 iPhone 是显示完页面才会触发脚本的执行。所以我们这边的解决方案延迟 JS 脚本的载入,这个方面的问题是需要Web前端工程师帮忙优化的。
**
*2:使用第三方 WebView 内核*