Android WebView探索

一、引言

WebView(网络视图)作用相当于一个迷你的浏览器,采用Webkit内核,因此完美支持html,javascript,css等。有时候,我们完 全可以把UI甚至数据处理都交给WebView,配合PHP等服务端程序,这样Android开发就变成了网页开发,可以省很多精力。目前很多android app都内置了可以显示web页面的界面,会发现这个界面一般都是由一个叫做WebView的组件渲染出来的,学习该组件可以为你的app开发提升扩展性。网上有很多介绍WebView相关的文章,我个人觉得比较好的一篇推荐给大家:Android WebView使用深入浅出 ,我在这里主要介绍Java代码怎么跟web通信。

二、WebView的使用说明

WebView是View的一个子类,可以让你在activity中显示网页。 在布局文件中写入WebView,比如下面这个写了一个填满整个屏幕的WebView:

<?xml version="1.0" encoding="utf-8"?>
<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
/>

加载一个网页,使用loadUrl():

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.baidu.com");

由于要访问网络,所以要在manifest中加上访问网络的权限:

<manifest ... > 
    <uses-permission android:name="android.permission.INTERNET" /> 
    ... 
</manifest>

这个时候发现一个问题,启动应用后,自动的打开了系统内置的浏览器,解决这个问题需要为webview设置 WebViewClient,并重写方法:

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

WebViewClient就是帮助WebView处理各种通知、请求事件,比如自己定义了一个页面加载进度的progressbar,需要展示给用户的时候,可以通过如下方式获取webview内页面的加载进度:

webview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                //get the newProgress and refresh progress bar
            }
        });

每个页面,都有一个标题,比如www.baidu.com这个页面的title即“百度一下,你就知道”,那么如何知道当前webview正在加载的页面的title呢:

webview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onReceivedTitle(WebView view, String title) {
                titleview.setText(title);//a textview
            }
        });

总之通过这个接口可以干自己的一些事, WebViewClient就是帮助WebView处理各种通知、请求事件

    //设置WebViewClient  
    webView.setWebViewClient(new WebViewClient(){     
        public boolean shouldOverrideUrlLoading(WebView view, String url) {     
            view.loadUrl(url);     
            return true;     
        }    
        public void onPageFinished(WebView view, String url) {  
            super.onPageFinished(view, url);  
        }  
        public void onPageStarted(WebView view, String url, Bitmap favicon) {  
            super.onPageStarted(view, url, favicon);  
        }  
    });
这个WebViewClient对象是可以自己扩展的,比如:
    private class MyWebViewClient extends WebViewClient {
        /*
         *为了继续在WebView中显示,需要重写shouldOverrideUrlLoading方法
         *默认返回:return super.shouldOverrideUrlLoading(view, url);
         *        这个返回的方法会调用父类方法,也就是跳转至手机浏览器。
         *返回true:webview处理url是根据程序来执行的。
         *返回false:webview处理url是在webview内部执行。
         */
        public boolean shouldOverrideUrlLoading(WebView view, String url) {  
            if (Uri.parse(url).getHost().equals("www.baidu.com")) {  
                return false;  
            }  
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));  
            startActivity(intent);  
            return true;  
        }  
    }
之后,我们就可以设置自己定义的WebViewClient了:
     WebView myWebView = (WebView) findViewById(R.id.webview);  
     myWebView.setWebViewClient(new MyWebViewClient());

另外,在WebViewClient中常用的方法:

  • doUpdateVisitedHistory(WebView view, String url, boolean isReload);         //更新历史记录
  • onFormResubmission(WebView view, Message dontResend, Message resend);    //重新请求网页数据
  • onLoadResource(WebView view, String url);              //加载指定网址提供的资源
  • onPageFinished(WebView view, String url);             //网页加载完毕
  • onPageStarted(WebView view, String url, Bitmap favicon);         //网页开始加载
  • onReceivedError(WebView view, int errorCode, String description, String failingUrl);  //加载页面出错

三、Android中java与web的通信

Android中Java与web通信不是新的技术了,在android发布之初就支持这种方式,这里我只是对android中的Java与web通信方式做一下总结。Android中有3种方式可以实现Java与web通信。

  1. 重写WebViewClient
private class MyWebViewClient extends WebViewClient {  
        @Override  
        public boolean shouldOverrideUrlLoading(WebView view, String url) {  
            if (Uri.parse(url).getHost().equals("www.demo.com")) {  
                // This is my web site, so do not override; let my WebView load the page  

                Toast.makeText(WebViewClientActivity.this, url, Toast.LENGTH_SHORT).show();  

                return false;  
            }  


            return true;  
        }  
    }  

通过shouldOverrideUrlLoading(WebView view, String url)返回的url获取数据,例如:url=“www.example.com?body=loadurl” 可以截取后面的body数据。
在web中调用方式:

<button onclick="window.open('www.demo.com?body=loadurl&#19;)">showTestToast</button>  

2、重写WebChromeClient

final class MyWebChromeClient extends WebChromeClient {  
       @Override  
       public boolean onJsAlert(WebView view, String url, String message, JsResult result) {  
           Log.d("MyWebChromeClient", message);  

           Toast.makeText(OnJsPromptActivity.this, message, Toast.LENGTH_SHORT).show();  
           result.confirm();  
           return true;  
       }  

    @Override  
    public boolean onJsConfirm(WebView view, String url, String message,  
            JsResult result) {  
        // TODO Auto-generated method stub  
        return super.onJsConfirm(view, url, message, result);  
    }  

    @Override  
    public boolean onJsPrompt(WebView view, String url, String message,  
            String defaultValue, JsPromptResult result) {  

         Toast.makeText(OnJsPromptActivity.this, message, Toast.LENGTH_SHORT).show();  
        // TODO Auto-generated method stub  
        //return super.onJsPrompt(view, url, message, defaultValue, result);  

         result.confirm();  
         return true;  
    }      
   }  

使用onJsAlert或者onJsPrompt,onJsAlert,onJsPrompt分别对应JS中的alert和prompt。
在web中调用方式:

<button onclick="showTestToast('Hello Android!');">showTestToast</button>  

<script type="text/javascript">  
    function showTestToast(toast) {  
        prompt('js prompt');    
    }  
  </script>  

3、addJavascriptInterface

mWebView.addJavascriptInterface(new WebAppInterface(this), "Android");  

public class WebAppInterface {  
        Context mContext;  

        /** Instantiate the interface and set the context */  
        WebAppInterface(Context c) {  
            mContext = c;  
        }  

addJavascriptInterface是Android提供的方法,包含两个参数。第一个是java中实现的类,类提供了javascript访问方法;第二个参数是java类映射到javascript的对象名。
在web中调用方式:

  <button onclick="showTestToast('addjavascriptinterface');">showTestToast</button>

  <script type="text/javascript">
    function showTestToast(toast) {
        Android.showToast(toast);
    }
  </script>

三种方法中后两种用的比较多。但是第三种方法在Android4.2一下存在安全漏洞,这种漏洞尤为在访问第三方地址时出现。在Android 4.2以上的,google作了修正,通过在Java的远程方法上面声明一个@JavascriptInterface。Android4.2以下还没有好的方法,只能限制访问特定地址实现安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值