智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...

导航

Android WebView使用

Posted on 2014-09-13 15:39  Bill Yuan  阅读(11485)  评论(0编辑  收藏  举报

转自:http://www.cnblogs.com/oakpip/archive/2011/04/08/2009800.html

大部分内容为网上整理其它高人的帖子,现只作整理,用于查看:

在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件。 
什么是webkit 
WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。 
传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过, 随着JavaScript引擎的独立性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,却仍然宣称自己是WebKit内核)。 
这里我们初步体验一下在android是使用webview浏览网页,在SDK的Dev Guide中有一个WebView的简单例子 。 
在开发过程中应该注意几点:     

1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。    

2.如果访问的页面中有Javascript,则webview必须设置支持Javascript。

  

webview.getSettings().setJavaScriptEnabled(true); 

WebView默认是不支持JavaScript 、IFrame或者是任何的框架语法的。通过设webview.getSettings().setJavaScriptEnabled(true);  就可以打开JavaScript.  webView.requestFocus()如果不设置的话,会出现不能弹出软键盘等问题。

3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。

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

4. postUrl(String url, byte[] postData) 加载页面使用Post方式,postData为参数

//    post方式传送参数
String postData = "clientID=cid&username=name";
webview.postUrl(url, EncodingUtils.getBytes(postData, "base64"));

 

5.如果不做任何处理,浏览网页,点击系统“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);       
    }     

 6.事件侦听

WebChromeClient:

 onCloseWindow(关闭WebView) 
 onCreateWindow() 
 onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出) 
 onJsPrompt 
 onJsConfirm 
 onProgressChanged 
 onReceivedIcon 
 onReceivedTitle

WebViewClient:

 onLoadResource:加载资源时响应
 onPageStart:在加载页面时响应
 onPageFinish:在加载页面结束时响应
 onReceiveError:在加载出错时响应
 onReceivedHttpAuthRequest:

//此方法可以处理webview 在加载时和加载完成时一些操作
webView.setWebChromeClient(new WebChromeClient(){
   @Override
   public void onProgressChanged(WebView view, int newProgress) {
    if(newProgress==100){                        
     // 这里是设置activity的标题, 也可以根据自己的需求做一些其他的操作
          title.setText("加载完成");
    }else{
     title.setText("加载中.......");
     }
    }
});


webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {  
    //重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边
     view.loadUrl(url);
       return true;
  }

     @Override
     public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) {
     // 重写此方法可以让webview处理https请求
    handler.proceed();
}
});

 

下一步让我们来了解一下android中webview是如何支持javascripte自定义对象的,在w3c标准中js有 window,history,document等标准对象,同样我们可以在开发浏览器时自己定义我们的对象调用手机系统功能来处理,这样使用js就可以 为所欲为了。

 

  看一个实例:

public class WebViewDemo extends Activity {
    private WebView mWebView;
    private Handler mHandler = new Handler();

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.webviewdemo);
        mWebView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        mWebView.addJavascriptInterface(new Object() {
            public void clickOnAndroid() {
                mHandler.post(new Runnable() {
                         public void run() { 
                            mWebView.loadUrl("javascript:wave()"); 
                        }   
                  });            
         }         
    }, "demo");         
    mWebView.loadUrl("file:///android_asset/demo.html");
    }   
}             

打开自定义的html

String customHtml = "<html><body><h1>Hello, WebView</h1></body></html>";
webView.loadData(customHtml, "text/html", "UTF-8");

我们看addJavascriptInterface(Object obj,String interfaceName)这个方法,该方法将一个java对象绑定到一个javascript对象中,javascript对象名就是 interfaceName(demo),作用域是Global。这样初始化webview后,在webview加载的页面中就可以直接通过 javascript:window.demo访问到绑定的java对象了。来看看在html中是怎样调用的。

<html>       
        <mce:script language="javascript"><!--     
                function wave() {       
                    document.getElementById("droid").src="android_waving.png";       
                }       
// --></mce:script>       
        <body>       
            <a onClick="window.demo.clickOnAndroid()">       
                                <img id="droid" src="android_normal.png" mce_src="android_normal.png"/><br>       
                                Click me!       
            </a>       
        </body>       
</html>      

这样在javascript中就可以调用java对象的clickOnAndroid()方法了,同样我们可以在此对象中定义很多方法(比 如发短信,调用联系人列表等手机系统功能。),这里wave()方法是java中调用javascript的例子。

这里还有几个知识点: 

1)为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html" 

2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用 Handler的目的。