Android WebView 开发详解(一)

396 篇文章 0 订阅
80 篇文章 0 订阅

Android WebView 开发详解(一)

  51221人阅读  评论(8)  收藏  举报
  分类:
 

目录(?)[+]

转载请注明出处  http://blog.csdn.net/typename/article/details/39030091 powered by meichal zhao  

概览:

          Android WebView在Android平台上是一个特殊的View, 他能用来显示网页,这个类可以被用来在你的app中仅仅显示一张在线的网页,还可以用来开发浏览器。WebView内部实现是采用渲染引擎来展示view的内容,提供网页前进后退,网页放大,缩小,搜索,前端开发者可以使用web inspector(Android 4.4系统支持,4.4一下可以采用http://developer.android.com/guide/webapps/debugging.html)调试HTML,CSS,Javascript等等功能。在Android 4.3系统及其一下WebView内部采用Webkit渲染引擎,在Android 4.4采用chromium 渲染引擎来渲染View的内容。

1.WebView的基本使用

 (1)创建WebView的实例加入到Activity view tree中   

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. WebView webview = new WebView(this);  
  2. setContentView(webview);  

  (2)在xml中配置WebView

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <Webview  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4. </Webview>  
  (3)访问网页

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. webview.loadUrl("http://developer.android.com/");  

2.WebView API使用详解

   1)请求加载网页部分
        
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void loadData (String data, String mimeType, String encoding)  

加载指定的data数据

参数说明:

data  字符串String形式的数据 可以通过base64编码而来

mineType data数据的 MIME类型, e.g. 'text/html'

encoding data数据的编码格式

Tips:

1.Javascript有同源限制,同源策略限制了一个源中加载文本或者脚本与来自其他源中的数据交互方式。避免这种限制可以使用loadDataWithBaseURL()方法。

2.encoding参数制定data参数是否为base64或者 URL 编码,如果data是base64编码那么 encoding必须填写 "base64“。

http://developer.android.com/reference/android/webkit/WebView.html

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)  
使用baseUrl加载base URL的网页内容,baseUrl解决相关url使用Javascript相同源问题。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void loadUrl (String url)  
加载制定url的网页内容

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void loadUrl (String url, Map<String, String> additionalHttpHeaders)  

加载制定url并携带http header数据。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void reload ()  

重新加载页面

Tip(重要)

页面所有资源会重新加载

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void stopLoading ()  


2) 前进后退

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void goBack ()  
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void goForward ()  
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void goBackOrForward (int steps)  
以当前的index为起始点前进或者后退到历史记录中指定的steps,  如果steps为负数则为后退,正数则为前进

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public boolean canGoForward ()  
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public boolean canGoBack ()  


3)JavaScript操作

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void addJavascriptInterface (Object object, String name)  

当网页需要和App进行交互时,可以注入Java对象提供给JavaScritp调用.  Java对象提供相应的方法供js使用.

Tips(重要)

问题:在Android 4.2以下使用这个api会涉及到JavaScript安全问题, javascript可以通过反射这个java对象的相关类进行攻击。

解决:可以采用白名单的机制调用这个方法.

在Android4.2极其以上系统需要给提供js调用的方法前加入一个注视:@JavaScriptInterface; 在虚拟机当中 Javascript调用Java方法会检测这个anotation,如果方法被标识@JavaScriptInterface则Javascript可以成功调用这个Java方法,否则调用不成功。

example:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class JsObject {  
  2.    @JavascriptInterface  
  3.    public String toString() { return "injectedObject"; }  
  4. }  
  5. webView.addJavascriptInterface(new JsObject(), "injectedObject");  

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void evaluateJavascript (String script, ValueCallback<String> resultCallback)  
这个方法在Android 4.4系统引入,因此只能在Android4.4系统中才能使用,提供在当前页面显示上下文中异步执行javascript代码

Tips(重要)

这个方法必须在UI线程调用,这个函数的回调也会在UI线程执行。

那么在Android4.4一下如何执行javascrit代码呢

可以通过 WebView提供的loadUrl方法:具体格式如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. webView.loadUrl("javascript:alert(injectedObject.toString())");  

其中javascript: 是执行javascript代码的标识 , 后面是javascript语句。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void removeJavascriptInterface (String name)  
删除addJavascripInterface时对webview注入的java对象. 此方法在不同的Android系统WebView会有问题,会存在失效情况。

4)网页查找功能

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public int findAll (String find)  
这个API在Android 4.1 就已经被去除, 在Android 4.1极其以上系统使用findAllAsync方法

这个API还存在bug 具体请见我的之前一篇博文Android WebView findAll bug

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void findAllAsync (String find)  
异步执行查找网页内包含的字符并设置高亮,查找结果会回调.

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void findNext (boolean forward)  
查找下一个匹配的字符

使用example:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class TestFindListener implements android.webkit.WebView.FindListener {  
  2.     private FindListener mFindListener;  
  3.   
  4.     public TestFindListener(FindListener findListener) {  
  5.         mFindListener = findListener;  
  6.     }  
  7.   
  8.     @Override  
  9.     public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,  
  10.             boolean isDoneCounting) {  
  11.         mFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);  
  12.     }  
  13. }  
  14.   
  15.    public void findAllAsync(String searchString) {  
  16.        if (android.os.Build.VERSION_CODES.JELLY_BEAN <= Build.VERSION.SDK_INT)  
  17.            mWebView.findAllAsync(searchString);  
  18.        else {  
  19.            int number = mWebView.findAll(searchString);  
  20.            if (mIKFindListener !=null)  
  21.                mIKFindListener.onFindResultReceived(number);  
  22.            fixedFindAllHighLight();  // 参见我之前一篇博文Android WebView API findAll bug  
  23.        }  
  24.    }  
  25.      
  26.    mWebView.findNext(forward);  

5)数据清除部分

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void clearCache (boolean includeDiskFiles)  
清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void clearFormData ()  
这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void clearHistory ()  
清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void clearMatches ()  
清除网页查找的高亮匹配字符

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void clearView ()  
在Android 4.3及其以上系统这个api被丢弃了, 并且这个api大多数情况下会有bug,经常不能清除掉之前的渲染数据。官方建议通过loadUrl("about:blank")来实现这个功能,阴雨需要重新加载一个页面自然时间会收到影响。

6)WebView的状态

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void onResume ()  
激活WebView为活跃状态,能正常执行网页的响应

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void onPause ()  
当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。并且可以减少不必要的CPU和网络开销,可以达到省电、省流量、省资源的效果。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void pauseTimers ()  

当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void resumeTimers ()  
恢复pauseTimers时的动作。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void destroy ()  
Tips(重要)

这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。

7) WebView 事件回调监听

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void setWebChromeClient (WebChromeClient client)  
主要通知客户端app加载当前网页的 title,Favicon,progress,javascript dialog等事件,通知客户端处理这些相应的事件。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void setWebViewClient (WebViewClient client)  
主要通知客户端app加载当前网页时的各种时机状态,onPageStart,onPageFinish,onReceiveError等事件。

8) Android 5.0 Lollipop 新API

public static void enableSlowWholeDocumentDraw ()

Android 5.0 Webview默认提供减少内存占用支持,并且智能选择需要绘制的HTML document部门来提供性能。 当然开发者可以在自己应用程序需要时关闭这个选项(enableSlowWholeDocumentDraw)。

3. WebView Demo

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.example.webviewdemo;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.app.Activity;  
  5. import android.content.Context;  
  6. import android.graphics.Bitmap;  
  7. import android.os.Message;  
  8. import android.webkit.WebChromeClient;  
  9. import android.webkit.WebSettings;  
  10. import android.webkit.WebView;  
  11. import android.webkit.WebViewClient;  
  12.   
  13. public class WebViewBase extends WebView {  
  14.     private static final String DEFAULT_URL = "http://www.ijinshan.com/";  
  15.     private Activity mActivity;  
  16.     public WebViewBase(Context context) {  
  17.         super(context);  
  18.         mActivity = (Activity) context;  
  19.         init(context);  
  20.     }  
  21.       
  22.     @SuppressLint("SetJavaScriptEnabled")  
  23.     private void init(Context context) {  
  24.         WebSettings webSettings = this.getSettings();  
  25.         webSettings.setJavaScriptEnabled(true);  
  26.         webSettings.setSupportZoom(true);  
  27.         //webSettings.setUseWideViewPort(true);  
  28.         this.setWebViewClient(mWebViewClientBase);  
  29.         this.setWebChromeClient(mWebChromeClientBase);  
  30.         this.loadUrl(DEFAULT_URL);  
  31.         this.onResume();  
  32.     }  
  33.       
  34.     private WebViewClientBase mWebViewClientBase = new WebViewClientBase();  
  35.       
  36.     private class WebViewClientBase extends WebViewClient {  
  37.   
  38.         @Override  
  39.         public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  40.             // TODO Auto-generated method stub  
  41.             return super.shouldOverrideUrlLoading(view, url);  
  42.         }  
  43.   
  44.         @Override  
  45.         public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  46.             // TODO Auto-generated method stub  
  47.             super.onPageStarted(view, url, favicon);  
  48.         }  
  49.   
  50.         @Override  
  51.         public void onPageFinished(WebView view, String url) {  
  52.             // TODO Auto-generated method stub  
  53.             super.onPageFinished(view, url);  
  54.         }  
  55.   
  56.         @Override  
  57.         public void onReceivedError(WebView view, int errorCode,  
  58.                 String description, String failingUrl) {  
  59.             // TODO Auto-generated method stub  
  60.             super.onReceivedError(view, errorCode, description, failingUrl);  
  61.         }  
  62.   
  63.         @Override  
  64.         public void doUpdateVisitedHistory(WebView view, String url,  
  65.                 boolean isReload) {  
  66.             // TODO Auto-generated method stub  
  67.             super.doUpdateVisitedHistory(view, url, isReload);  
  68.         }  
  69.     }  
  70.       
  71.     private WebChromeClientBase mWebChromeClientBase = new WebChromeClientBase();  
  72.       
  73.     private class WebChromeClientBase extends WebChromeClient {  
  74.   
  75.         @Override  
  76.         public void onProgressChanged(WebView view, int newProgress) {  
  77.             mActivity.setProgress(newProgress * 1000);  
  78.         }  
  79.   
  80.         @Override  
  81.         public void onReceivedTitle(WebView view, String title) {  
  82.             // TODO Auto-generated method stub  
  83.             super.onReceivedTitle(view, title);  
  84.         }  
  85.   
  86.         @Override  
  87.         public void onReceivedTouchIconUrl(WebView view, String url,  
  88.                 boolean precomposed) {  
  89.             // TODO Auto-generated method stub  
  90.             super.onReceivedTouchIconUrl(view, url, precomposed);  
  91.         }  
  92.   
  93.         @Override  
  94.         public boolean onCreateWindow(WebView view, boolean isDialog,  
  95.                 boolean isUserGesture, Message resultMsg) {  
  96.             // TODO Auto-generated method stub  
  97.             return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);  
  98.         }  
  99.           
  100.     }  
  101. }  

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <uses-permission android:name="android.permission.INTERNET" />  


转载请注明出处  http://blog.csdn.net/typename/article/details/39030091 powered by meichal zhao

有问题欢迎讨论

1





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值