Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2122086
  • 博文数量: 229
  • 博客积分: 7217
  • 博客等级: 上校
  • 技术积分: 3224
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-19 17:23
个人简介

个人主页https://xugaoxiang.com,微信公众号: Dev_Club 或者搜索 程序员Club

文章分类

全部博文(229)

文章存档

2017年(1)

2016年(20)

2015年(23)

2013年(1)

2012年(23)

2011年(68)

2010年(62)

2009年(31)

分类: Android平台

2015-10-26 15:44:31

软硬件环境

  • Macbook Pro MGX 72
  • Android Studio 1.4
  • 坚果手机、Genymotion模拟器

前言

WebView是Android中用来显示网页内容的一个控件。随着前端技术的不断发展,WebView也被使用得越来越普遍,更有甚者,有的App只有一个WebView控件,所有的内容与事件响应都在服务器端中进行,这在Android TV中比较常见。

常规使用方法

要想使用WebView访问网页,需要在AndroidManifest.xml文件中加入网络访问的权限

 

在布局文件中声明WebView控件,属性在后面讲,这里是全屏显示




    
 

在Java文件中使用

WebView webView = (WebView) findViewById(R.layout.webView);
//打开对javascript的支持
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://blog.csdn.net/djstavav"); 

这样,网页就可以正常打开了,如下图

常用XML属性

xml属性 详细说明
scrollbars 滚动条(horizontal、vertical、none)
focusableInTouchMode view在触摸时是否能够获取焦点

显示本地页面

一般在页面访问中,不变的页面信息可以通过显示本地预存网页文件的形式来达到效果,而不需要去服务器端重新抓取,进而提升了app的性能。如常见的404错误页面。 首先准备一个html文件demo.html,这里仅显示一条简单的文本信息


    
        
    

 

将上面的html文件存放在工程中的assets文件夹中,如果该文件夹不存在,请自行创建,然后利用WebView去访问此html文件

webView.loadUrl("file:///android_asset/demo.html"); 

注意: “android_asset”字段是固定要这样写的,显示的效果如下图

显示加载进度

这里需要用到WebView的另一个方法setWebChromeClient,重写onProgressChanged方法

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);

        setTitle("Loading ... " + newProgress + "%");
        setProgress(newProgress * 100);
        if (newProgress == 100) {
            setTitle("Loading completely.");
        }
    }

}); 

页面缩放

双击放大,再次双击还原

webView.getSettings().setBuiltInZoomControls(true); 

PS: 如果要使用缩放功能,务必不要将WebView布局中的宽度或高度设置为wrap_content

点击超级链接在当前WebView里跳转

如果按照上面的方法打开了我的博客首页,再点击某一篇博文时,会发现,新的页面会在系统的默认浏览器中打开,这显然不是我们想要看到的。如果想要在当前的WebView里打开页面,需要用到WebView的setWebViewClient方法,如下

 webView.setWebViewClient(new WebViewClient() {
     @Override
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
         view.loadUrl(url);
         return super.shouldOverrideUrlLoading(view, url);
     }
 }); 

Android TV中WebView的按键响应问题

当布局中是一个WebView时,打开页面后,焦点就移到了WebView上,默认情况下,此时遥控器只响应返回键,如果需要响应其它键值(比如菜单键),这时该怎么做呢?

一般的键值处理是放在onKeyDown(int keyCode,KeyEvent keyevent)里处理的,不过在上述场景中,onKeyDown方法中接收不到菜单键,如果想让其也能够接收到,也不难,往下看。

@Override
public boolean shouldOverrideKeyEvent(WebView webView,KeyEvent keyEvent) {
    //让onKeyDown来处理KeyEvent.KEYCODE_STAR,此处以小红遥控器菜单键为例
    if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_STAR) {
        return true;
    } else {
        return false;
    }
} 

重写了上述方法以后,再去重写onKeyDown,捕捉对应的按键进行处理。

返回WebView的上一页面

需要重写onKeyDown方法,并捕捉返回键并判断,调用WebView的goBack方法

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { 
        webview.goBack(); //goBack()表示返回WebView的上一页面 
        return true; 
    } 
    return false; 
} 

Javascript调用Java方法

关于这一点的实现,之前写过一篇博文,请参考

<http://blog.csdn.net/djstavav/article/details/48212083>

提升渲染优先级

设置渲染线程的优先级别,这个属性每个进程只需要被调用一次。在API level 22中已经被弃用。

webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH); 

不加载网络中的图片资源

在某些特殊情况下,可以设置不加载网页中的图片

webView.getSettings().setBlockNetworkImage(true); 

有效利用缓存

默认的cache目录是/data/data/包名/cache,可以通过getCacheDir方法来查看。

webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 

优先从本地cache中载入,其次才是从网络中载入,即使cache已经过期。对应着Web Server Apache来查看,/var/log/apache2/access.log,可以看到,前后2次http请求同一张图片时的结果,第2次,http返回的code是304,表明资源并未从服务器端获取,而是从本地Pcache中获取。

源码下载

<>

参考文献

阅读(2487) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~