最近做的项目大量用到了 webview ,用网页来布局。 Android  webview 是基于 webkit 内核,不过他的运行效果和 firefox 上一模一样,所以写的时候都是先用 firefox 测试,测试 OK 了再放到程序里面看效果,基本上不会有什么问题。其实 android  webview  iphone  webview 差不多, iphone上的 webview  android 上的强大多了。

谈一下研究 webview 的一些成果:


一.    加载资源的速度不慢,但是资源多了,就很慢。图片、 css  js  html 这些资源每个大概需要10-200ms ,一般都是 30ms  ok 了。如果一个页面上的资源很多,就很浪费时间。


二.    Js  css 的执行速度。开始的时候,我的页面都是用 js 生成 DOM ,添加样式等也用 js 添加。后来发现,加载一个页面居然要 5-6 秒。然后我就怀疑是不是 js 的执行效率不高,然后就把能用 css的地方都用 css ,能直接写到 html 上的就不用 js 动态生成。结果,速度并没有多大的提升,最多提升了 1 秒。看来, Js 的执行速度虽然比不上 css ,但是还不至于慢到那种程度。那会是什么原因使得页面加载速度这么慢?经过仔细的排查,最终发现,是因为我用了 jQuery 框架。

Webview 加载页面的顺序是这样的:先加载 html ,然后从里面解析出 css  js 文件和页面上写死的图片资源进行加载,如果 webkit 的缓存里面有,就不加载。加载完这些资源之后,就进行 css 的渲染和 js 的执行。 Css 的渲染一般不需要很长时间,几十毫秒就 ok 。关键是 js 的执行,如果用了jQuery ,则执行起来需要 5-6 秒。而在这段时间,如果不在 webview 里设置背景,网页部分是白色的,很难看。这是一个很糟糕的用户体验。所以如果用网页布局程序,最好别用很大的 js 框架。


三.     网页和 Java 之间的互调。这个功能是 iphone 里面就有的,网上也有很多资料,可以告诉我们怎么做,这些都是很简单、很基本的。我研究了一段时间,总结一下:

 1.  Java 调用 js 里面的函数,速度并不令人满意,大概一次一两百毫秒吧,如果要做交互性很强的事情,这种速度会让人疯掉的。而反过来就不一样了, js 去调 java 的方法,速度很快,基本上 40-50毫秒一次。所以尽量用 js 调用 java 方法,而不是 java 去调用 js 函数。

 2.  Java 调用 js 的函数,没有返回值,而 Js 调用 java 方法,可以有返回值。返回值可以是字符串,也可以是对象。如果是字符串,有个很讨厌的问题,第 3 点我会讲的。如果是对象,这个对象会被转换为 js 的对象,直接可以访问里面的方法。但是我不推荐 java 返回给 js 的是对象,除非是必须。因为js 收到 java 返回的对象,会产生一些交换对象,而如果这些对象的数量增加到了 500  600 以上,程序就会出问题。所以尽量返回基本数据类型或者字符串。

3.  Js 调用 java 的方法,返回值如果是字符串,你会发现这个字符串是 native 的,不能对它进行一些修改操作,比如想对它 substr ,取不到。怎么解决呢?转成 locale 的。使用 toLocaleString() 函数就可以了。不过这个函数的速度并不快,转化的字符串如果很多,将会很耗费时间。




四.        网页上拖动元素。网页上有一个 div ,想要拖动它到另外一个地方,怎么做?如果用 PC 上的网页做法,监听 onmousedown  onmousemove  onmouseup 就可以了。但是在手机上,事件模型就不一样了。在网页上点击,拖动,然后释放,手离开屏幕的时候, webview 才会触发onmousedown  onmousemove  onmouseup 事件。所以,要想拖动,不能这么做。这个问题困扰我很长时间,后来发现 iphone 上的做法,才解决了。 Iphone 上的 webview 有专为触摸屏设计的事件ontouchstart  ontouchmove  ontouchend ,这几个事件的响应是实时的,就能解决拖动的问题了。


五.        一些小问题。 Webview 里面的网页,如果有 input ,需要输入,但是点上去却没反应,输入法不出来。这种情况是因为 webview 没有获取焦点。需要在 java 里面给 webview 设置一下requestFocus() 就行了。


六.        Android 上的 webview  iphone  webview 区别。目前为止,我发现的区别有这么几个:

1  Android 上, webview 不支持多点触控,没有 ongesture 系列事件,而 iphone 上有。

      2  Android 上的 webview 不支持透明, iphone 上可以。


暂时就能想到这么些,还有很多以后再补充吧。

 

 

评论
12 楼 chroya 2010-10-15   引用
mingyueqianshen 写道
你好,我想请问下return super.shouldOverrideUrlLoading(view, url);怎么解释?shouldOverrideUrlLoading();的返回值true和false有什么区别??

shouldOverrideUrlLoading方法指明了在loadUrl的时候,程序应该有怎样的行为。
如果是返回false,则url由当前的webview载入,如果是true,则交给当前程序来决定如何处理。
11 楼 mingyueqianshen 2010-10-14   引用
你好,我想请问下return super.shouldOverrideUrlLoading(view, url);怎么解释?shouldOverrideUrlLoading();的返回值true和false有什么区别??
10 楼 jaymsimusic 2010-09-02   引用
jaymsimusic 写道
Java代码 
  1. webView.loadUrl("http://localhost/dici/property/listPropertyInfoByDeviceUnit.action");  
  2. //webView.loadUrl("file:///android_asset/listPropertyInfoByDeviceUnit.html");  
  3. webView.loadUrl("javascript:getValidationJS()");  

你好,想请教个问题,我现在用webView.loadUrl() 装载的是动态页面,不是本地assets中的页面,然后在 webView中调用 js 好像不行,我想问下 webView能调用动态页面中的js方法吗? 
谢谢了。

搞定了  原来我在页面用js回调android中的java方法时不能传Integer,把java方法的参数类型改成String 就ok了。
9 楼 chroya 2010-09-02   引用
jaymsimusic 写道
Java代码 
  1. webView.loadUrl("http://localhost/dici/property/listPropertyInfoByDeviceUnit.action");  
  2. //webView.loadUrl("file:///android_asset/listPropertyInfoByDeviceUnit.html");  
  3. webView.loadUrl("javascript:getValidationJS()");  

你好,想请教个问题,我现在用webView.loadUrl() 装载的是动态页面,不是本地assets中的页面,然后在 webView中调用 js 好像不行,我想问下 webView能调用动态页面中的js方法吗?
谢谢了。

一样是可以使用的,不过有个javascript开关需要打开,类似webView.getSettings().setJavaScriptEnabled(true);这样子。
8 楼 jaymsimusic 2010-09-02   引用
Java代码 
  1. webView.loadUrl("http://localhost/dici/property/listPropertyInfoByDeviceUnit.action");  
  2. //webView.loadUrl("file:///android_asset/listPropertyInfoByDeviceUnit.html");  
  3. webView.loadUrl("javascript:getValidationJS()");  

你好,想请教个问题,我现在用webView.loadUrl() 装载的是动态页面,不是本地assets中的页面,然后在 webView中调用 js 好像不行,我想问下 webView能调用动态页面中的js方法吗? 
谢谢了。
7 楼 chroya 2010-07-29   引用
shadowlin 写道
chroya 写道
@shadowlin  
我说的及时响应就是指一进入应用立即就把页面显示出来。应用加载以后,执行功能的时候,基本上不会有什么延迟的。
另外,2.2的系统对webkit做过优化,大概比以前的版本快3倍左右。


这样啊。不用jquery以后速度快了很多么?
你的js大概有多少k?

我做的页面,不用jquery以后,再加上了一些优化,页面几乎是瞬间加载,1秒不到。每个页面的js大概有二十几K,都是单个的function,没有加载的时候执行的代码。
6 楼 shadowlin 2010-07-28   引用
chroya 写道
@shadowlin  
我说的及时响应就是指一进入应用立即就把页面显示出来。应用加载以后,执行功能的时候,基本上不会有什么延迟的。 
另外,2.2的系统对webkit做过优化,大概比以前的版本快3倍左右。


这样啊。不用jquery以后速度快了很多么? 
你的js大概有多少k?
5 楼 chroya 2010-07-20   引用
@shadowlin  
我说的及时响应就是指一进入应用立即就把页面显示出来。应用加载以后,执行功能的时候,基本上不会有什么延迟的。
另外,2.2的系统对webkit做过优化,大概比以前的版本快3倍左右。
4 楼 shadowlin 2010-07-20   引用
chroya 写道
shadowlin 写道
jquery不算是很大的框架吧。 
在webview里里面的js引擎和浏览器的应该是一个吧? 
浏览器里访问用jquery的网站速度还可以啊

jquery是不算很大,但是加载需要好几秒的时间,如果是浏览网页的话,当然不会觉得慢,但是如果要做即时相应的那种页面,几秒的时间就接受不了了。


郁闷,刚才发的没有掉了。 

我用n1(2.2系統)测试加载我的应用,大概10000行左右js代码+jquery,基本没有响应时间。在1.6(rockchip2808)上面大概要加载2-3秒钟。但是一次加载完成后就很快了。 
不知道你说即时响应是不是指要求一进入应用立即就把页面显示出来,还是在应用加载以后执行里面的功能会有延迟。 
 
3 楼 TremendousTurtle 2010-07-19   引用
最近在写一个程序,用的是webview加载网页的方式,程序有时候会卡死,不知道是不是跟jquery有关。
有相关需求的朋友请加我QQ 76719910, 共同研究
2 楼 chroya 2010-07-17   引用
shadowlin 写道
jquery不算是很大的框架吧。
在webview里里面的js引擎和浏览器的应该是一个吧?
浏览器里访问用jquery的网站速度还可以啊

jquery是不算很大,但是加载需要好几秒的时间,如果是浏览网页的话,当然不会觉得慢,但是如果要做即时相应的那种页面,几秒的时间就接受不了了。
1 楼 shadowlin 2010-07-10   引用
jquery不算是很大的框架吧。 
在webview里里面的js引擎和浏览器的应该是一个吧? 
浏览器里访问用jquery的网站速度还可以啊