webview使用总结及注意事项
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 上可以。
webview使用总结及注意事项的更多相关文章
- WebView注入Java对象注意事项
在android4.2以前,注入步骤如下: webview.getSetting().setJavaScriptEnable(true); class JsObject { public String ...
- Android WebView的loadData方法注意事项
loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,出现这种字符就会出现解析错误,显示找不到网页还有部分html代码.需要如何处理呢?我们需要用Url ...
- Webview的使用和注意事项
1.webView是一个展示web网页的控件,继承 AbsoluteLayout 2.webview的俩个回调应用层: 1)webViewClient 这个对象的创建 WebViewClient my ...
- Android WebView中那些不得不解决的坑~~
前面那张hybrid开发心得 有人问 怎么解决不用onJsPrompt 来回调js函数的问题.其实很简单,就是在在你的jscalljava回调函数内 另外开个线程去load js代码即可: wb.po ...
- 关于Android4.2后WebView的js方法需要加@JavascriptInterface
解读: targetSdkVersion>=17时,需要加上@JavascriptInterface,否则报错Uncaught TypeError: Object [object Object] ...
- WebView JS交互 JSBridge 案例 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- iOS开发常见BUG和一些小技巧(ps:耐心看完,很实用)
[385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Created by beyond on 15/6/6. // Copyright ...
- android + javascript 相互通信实例分析
1. AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误 ...
- iOS开发中遇到的一些问题及解决方案【转载】
iOS开发中遇到的一些问题及解决方案[转载] 2015-12-29 [385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Creat ...
随机推荐
- CentOS 6.5 安装Oracle 11G R2问题列表
1. 文章中写vi/etc/profile #这个很重要 if [ $USER ="oracle" ]; then if [ $SHELL="/bin/ksh&q ...
- Nginx+tomcat负载均衡时静态页面报404
百度到的问题解决BLOG http://os.51cto.com/art/201204/326843.htm nginx+2台tomcat负载均衡,应用程序已部署,单独访问tomcat时,可以访问到所 ...
- Android 遮罩层效果
(用别人的代码进行分析) 不知道在开发中有没有经常使用到这种效果,所谓的遮罩层就是给一张图片不是我们想要的形状,这个时候我们就可以使用遮罩效果把这个图片变成我们想要的形状,一般使用最多就是圆形的效果, ...
- PHP向mysql中插入数据的方法
require "database.php"; $po_code = "YMWF2015-6-25-1"; $customer = "youmei&q ...
- 非阻塞同步算法实战(三)-LatestResultsProvider
本人是本文的作者,首发于ifeve(非阻塞同步算法实战(三)-LatestResultsProvider) 前言 阅读本文前,需要读者对happens-before比较熟悉,了解非阻塞同步的一些基本概 ...
- css实现并列效果
<a href="#" class="mj-picList"> <div class="mj-picList-pic" s ...
- csrf跨站请求伪造
如何杜绝跨站请求伪造? 1.要让服务器知道本次请求是不是冒用了用户的身份→ 2.服务器发给用户一个凭证,用户请求时需携带此凭证→ 3.此凭证只能用户看到而且冒用者看不到→ 4.这就用到了浏览器的安全机 ...
- 集合类List,set,Map 的遍历方法,用法和区别
遍历list: 方法一: for(String s:lists){ System.out.println(s); } 方法二: System.out.println("list with i ...
- 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案
方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...
- Git 教程
Git 教程 新建 模板 小书匠 欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过设置里的修改模板来改变新建文章的内容. Git使用 Git - 关于版本控制 TortoiseGit日常 ...