1 网页 调用后台java代码 ,后台处理
一 网页上click事件
<a href="javascript:;" onclick="window.JsNativeMethod.showPropDetailPage(${item.id})" class="a-link">
<img src="${item.imgUrl}">
</a>
<a class="txt-link txtof" href="javascript:;" onclick="window.JsNativeMethod.showPropDetailPage(${item.id})">
${item.goodsName}
</a>
二 后台代码,定义JavascriptInterface
private class JsNativeMethod{
@android.webkit.JavascriptInterface
public void showPropDetailPage(int propId){
Message msg = Message.obtain();
msg.what = MSG_SHOWPROPDETIAL;
msg.arg1 = propId;
mUiHandler.sendMessage(msg);
}
}
三 mWebView.setWebViewClient(new ExWebViewClient());
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JsNativeMethod(), "JsNativeMethod");
mWebView.loadUrl("http://app.ujux.com/index.jsp");
2 监控事件
private class ExWebViewClient extends WebViewClient{//主要监控url跳转,拦截,请求
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//1 实例化webview 2 设置setting配置 3 指定webclient方法,监听点击链接以及url跳转
//return false 在当前webview内部跳转 ;return true 则交给当前程序来决定如何处理
// 默认返回:return super.shouldOverrideUrlLoading(view, url); 也就是跳转至手机浏览器
///在手机浏览器中打开当前url
intent ints=new Intent(Intent.Action_view);
ints.setData(uri.parse(url))
startActivity(ints);
return true;
}
mWebView.setWebChromeClient(new WebChromeClient() { //主要监控js ,alert,confirm,prompt;处理Javascript的对话框,网站图标,网站title,加载进度等
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.e(TAG, "onJsAlert " + message);
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
result.confirm();
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
Log.e(TAG, "onJsConfirm " + message);
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Log.e(TAG, "onJsPrompt " + url);
return super.onJsPrompt(view, url, message, defaultValue, result);
}
});
mWebView.loadUrl(url);
}
//和shouldoverrideUrlLoading()区别,点击连接都会执行,返回前个页面只会执行onPageStarted()
也就是说,onpageStarted()任何时候都执行 ;前者先执行//
@Override
public void onPageStarted{}
@Override
public void onPageFinished(WebView view, String url) {
if(url.contains("prodlist")){ //包含此字符串则认为webview已跳至二级页面
mBackBtn.setVisibility(View.VISIBLE);
}else{
mBackBtn.setVisibility(View.GONE);
}
}
}
3 webviewclient常用事件说明
一 打开链接前的事件
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }
这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。
二 onLoadResource:加载资源时响应
三 载入页面完成的事件
public void onPageFinished(WebView view, String url){ }
同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。
四 载入页面开始的事件
public void onPageStarted(WebView view, String url, Bitmap favicon) { }
这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
五
onReceiveError:在加载出错时响应
onReceivedHttpAuthRequest:接收到 Http 请求的事件
注意:
1 如果在onPageStarted里写的话,最好不要出现view.loadUrl(url);因为如果有这个,页面会一直在这里跳动,至少我都注释掉也没发现报错。。。
还有就是如果里面逻辑判断很多,那么一定要想好该怎么放怎么写,并不是shouldOverrideUrlLoading 里怎么写 onPageStarted 里面就必须写的。。。。。
2 js的几种写法会引起shouldOverrideUrlLoading无效啊,贴出来供大家看哦,也好注意可千万别弄成这样。。。。
以下这个url打开的动作,自定义的webview截获不了:
a. js中setTime之后,自定义的webview截获不了
b. Ajax中,作为callback处理,给location.href赋值
c. form提交中的url迁移
http://tanghaibo001.blog.163.com/blog/static/9068612020121023113646644/
3 设置WevView要显示的网页:
互联网用:webView.loadUrl("http://www.google.com");
本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets文件中
http://www.oschina.net/question/157182_46137
4 addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,否则容易导致webviewclient中的onPageStart方法与addJavascriptInterface
中的方法起了冲突,二个人的执行顺序时常互换,改成handlder实现,就解决其中的问题,正确的顺序是onPageStart在addJavascriptInterface中的handlder事件处理之前执行)。
//java后台调用js中的函数//
四 ((WebLayout) _vCurCenterBodyView).m_vCurWebView.loadUrl("javascript:hot();");
总结:
Java 调用 js 里面的函数,速度并不令人满意,大概一次一两百毫秒吧,如果要做交互性很强的事情,这种速度会让人疯掉的。而反过来就不一样了, js 去调 java 的方法,速度很快,基
本上 40-50毫秒一次。所以尽量用 js 调用 java 方法,而不是 java 去调用 js 函数。
在页面用js回调android中的java方法时不能传Integer,把java方法的参数类型改成String
五 网页回退用 goBack()方法
如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事
件。
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
六 webview缓存,数据库api
1 当我们加载Html时候,会在我们data/应用package下生成database与cache两个文件夹:
我们请求的Url记录是保存在webviewCache.db里,而url的内容是保存在webviewCache文件夹下.
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源)、H5缓存(即AppCache);
http://blog.csdn.net/top_code/article/details/17024745
2 网页缓存
1、缓存构成
/data/data/package_name/cache/webviewCache
/data/data/package_name/database/webview.db
/data/data/package_name/database/webviewCache.db
2 设置缓存配置:
private void initWebView() {
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); //设置 缓存模式
// 开启 DOM storage API 功能
mWebView.getSettings().setDomStorageEnabled(true);
//开启 database storage API 功能
mWebView.getSettings().setDatabaseEnabled(true);
String cacheDirPath = getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME;
// String cacheDirPath = getCacheDir().getAbsolutePath()+Constant.APP_DB_DIRNAME;
Log.i(TAG, "cacheDirPath="+cacheDirPath);
//设置数据库缓存路径
mWebView.getSettings().setDatabasePath(cacheDirPath);
//设置 Application Caches 缓存目录
mWebView.getSettings().setAppCachePath(cacheDirPath);
//开启 Application Caches 功能
mWebView.getSettings().setAppCacheEnabled(true);
}
/**
* 清除WebView缓存
*/
public void clearWebViewCache(){
//清理Webview缓存数据库
try {
deleteDatabase("webview.db");
deleteDatabase("webviewCache.db");
} catch (Exception e) {
e.printStackTrace();
}
//WebView 缓存文件
File appCacheDir = new File(getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME);
Log.e(TAG, "appCacheDir path="+appCacheDir.getAbsolutePath());
File webviewCacheDir = new File(getCacheDir().getAbsolutePath()+"/webviewCache");
Log.e(TAG, "webviewCacheDir path="+webviewCacheDir.getAbsolutePath());
//删除webview 缓存目录
if(webviewCacheDir.exists()){
deleteFile(webviewCacheDir);
}
//删除webview 缓存 缓存目录
if(appCacheDir.exists()){
deleteFile(appCacheDir);
}
}
七 webview优化
1 可直接在本地设置网络代理,直接把整个网页数据下载到本地,在加载
2 预加载图片
3 启用缓存 和 数据库
4 较小页面要加载资源的体积,js,css,图片压缩
八 webview网页执行顺序
Webview 加载页面的顺序是这样的:先加载 html ,然后从里面解析出 css 、 js 文件和页面上写死的图片资源进行加载,如果 webkit 的缓存里面有,就不加载。加载完这些资源之后,就
进行 css 的渲染和 js 的执行。
九 DownloadListener接口!!
该接口里面有一个方法,onDownloadStart()下载侦听接口,如果客户代码实现该接口,则在下载开始、失败、挂起、完成等情况下,DownloadManagerCore对象会调用客户代码中实现的
DownloadListener方法。
九 经验和问题
1 Android 的 webview 是基于 webkit 内核,不过他的运行效果和 firefox 上一模一样,所以写的时候都是先用 firefox 测试,测试 OK 了再放到程序里面看效果,基本上不会有什么问题
。
2 webview 有专为触摸屏设计的事件ontouchstart 、 ontouchmove 、 ontouchend ,这几个事件的响应是实时的,就能解决拖动的问题了。
3 Webview 里面的网页,如果有 input ,需要输入,但是点上去却没反应,输入法不出来。这种情况是因为 webview 没有获取焦点。需要在 java 里面给 webview 设置一下requestFocus()
就行了。
4 Android 上的 webview 和 iphone 的 webview 区别。目前为止,我发现的区别有这么几个:
1 . Android 上, webview 不支持多点触控,没有 ongesture 系列事件,而 iphone 上有。
2 . Android 上的 webview 不支持透明, iphone 上可以。