Android WebView 开发详解(一)
转载请注明出处 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中
- WebView webview = new WebView(this);
- setContentView(webview);
(2)在xml中配置WebView
- <Webview
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- </Webview>
(3)访问网页
- webview.loadUrl("http://developer.android.com/");
2.WebView API使用详解
- 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
- public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
使用baseUrl加载base URL的网页内容,baseUrl解决相关url使用Javascript相同源问题。
- public void loadUrl (String url)
加载制定url的网页内容
- public void loadUrl (String url, Map<String, String> additionalHttpHeaders)
加载制定url并携带http header数据。
- public void reload ()
重新加载页面
Tip(重要)
页面所有资源会重新加载
- public void stopLoading ()
2) 前进后退
- public void goBack ()
- public void goForward ()
- public void goBackOrForward (int steps)
以当前的index为起始点前进或者后退到历史记录中指定的steps, 如果steps为负数则为后退,正数则为前进
- public boolean canGoForward ()
- public boolean canGoBack ()
3)JavaScript操作
- 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:
- class JsObject {
- @JavascriptInterface
- public String toString() { return "injectedObject"; }
- }
- webView.addJavascriptInterface(new JsObject(), "injectedObject");
- public void evaluateJavascript (String script, ValueCallback<String> resultCallback)
这个方法在Android 4.4系统引入,因此只能在Android4.4系统中才能使用,提供在当前页面显示上下文中异步执行javascript代码
Tips(重要)
这个方法必须在UI线程调用,这个函数的回调也会在UI线程执行。
那么在Android4.4一下如何执行javascrit代码呢
可以通过 WebView提供的loadUrl方法:具体格式如下:
- webView.loadUrl("javascript:alert(injectedObject.toString())");
其中javascript: 是执行javascript代码的标识 , 后面是javascript语句。
- public void removeJavascriptInterface (String name)
删除addJavascripInterface时对webview注入的java对象. 此方法在不同的Android系统WebView会有问题,会存在失效情况。
4)网页查找功能
- public int findAll (String find)
这个API在Android 4.1 就已经被去除, 在Android 4.1极其以上系统使用findAllAsync方法
这个API还存在bug 具体请见我的之前一篇博文Android WebView findAll bug
- public void findAllAsync (String find)
异步执行查找网页内包含的字符并设置高亮,查找结果会回调.
- public void findNext (boolean forward)
查找下一个匹配的字符
使用example:
- public class TestFindListener implements android.webkit.WebView.FindListener {
- private FindListener mFindListener;
- public TestFindListener(FindListener findListener) {
- mFindListener = findListener;
- }
- @Override
- public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
- boolean isDoneCounting) {
- mFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
- }
- }
- public void findAllAsync(String searchString) {
- if (android.os.Build.VERSION_CODES.JELLY_BEAN <= Build.VERSION.SDK_INT)
- mWebView.findAllAsync(searchString);
- else {
- int number = mWebView.findAll(searchString);
- if (mIKFindListener !=null)
- mIKFindListener.onFindResultReceived(number);
- fixedFindAllHighLight(); // 参见我之前一篇博文Android WebView API findAll bug
- }
- }
- mWebView.findNext(forward);
5)数据清除部分
- public void clearCache (boolean includeDiskFiles)
清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
- public void clearFormData ()
这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。
- public void clearHistory ()
清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.
- public void clearMatches ()
清除网页查找的高亮匹配字符
- public void clearView ()
在Android 4.3及其以上系统这个api被丢弃了, 并且这个api大多数情况下会有bug,经常不能清除掉之前的渲染数据。官方建议通过loadUrl("about:blank")来实现这个功能,阴雨需要重新加载一个页面自然时间会收到影响。
6)WebView的状态
- public void onResume ()
激活WebView为活跃状态,能正常执行网页的响应
- public void onPause ()
当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。并且可以减少不必要的CPU和网络开销,可以达到省电、省流量、省资源的效果。
- public void pauseTimers ()
当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
- public void resumeTimers ()
恢复pauseTimers时的动作。
- public void destroy ()
Tips(重要)
这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。
7) WebView 事件回调监听
- public void setWebChromeClient (WebChromeClient client)
主要通知客户端app加载当前网页的 title,Favicon,progress,javascript dialog等事件,通知客户端处理这些相应的事件。
- 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
- package com.example.webviewdemo;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.os.Message;
- import android.webkit.WebChromeClient;
- import android.webkit.WebSettings;
- import android.webkit.WebView;
- import android.webkit.WebViewClient;
- public class WebViewBase extends WebView {
- private static final String DEFAULT_URL = "http://www.ijinshan.com/";
- private Activity mActivity;
- public WebViewBase(Context context) {
- super(context);
- mActivity = (Activity) context;
- init(context);
- }
- @SuppressLint("SetJavaScriptEnabled")
- private void init(Context context) {
- WebSettings webSettings = this.getSettings();
- webSettings.setJavaScriptEnabled(true);
- webSettings.setSupportZoom(true);
- //webSettings.setUseWideViewPort(true);
- this.setWebViewClient(mWebViewClientBase);
- this.setWebChromeClient(mWebChromeClientBase);
- this.loadUrl(DEFAULT_URL);
- this.onResume();
- }
- private WebViewClientBase mWebViewClientBase = new WebViewClientBase();
- private class WebViewClientBase extends WebViewClient {
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- // TODO Auto-generated method stub
- return super.shouldOverrideUrlLoading(view, url);
- }
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- // TODO Auto-generated method stub
- super.onPageStarted(view, url, favicon);
- }
- @Override
- public void onPageFinished(WebView view, String url) {
- // TODO Auto-generated method stub
- super.onPageFinished(view, url);
- }
- @Override
- public void onReceivedError(WebView view, int errorCode,
- String description, String failingUrl) {
- // TODO Auto-generated method stub
- super.onReceivedError(view, errorCode, description, failingUrl);
- }
- @Override
- public void doUpdateVisitedHistory(WebView view, String url,
- boolean isReload) {
- // TODO Auto-generated method stub
- super.doUpdateVisitedHistory(view, url, isReload);
- }
- }
- private WebChromeClientBase mWebChromeClientBase = new WebChromeClientBase();
- private class WebChromeClientBase extends WebChromeClient {
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- mActivity.setProgress(newProgress * 1000);
- }
- @Override
- public void onReceivedTitle(WebView view, String title) {
- // TODO Auto-generated method stub
- super.onReceivedTitle(view, title);
- }
- @Override
- public void onReceivedTouchIconUrl(WebView view, String url,
- boolean precomposed) {
- // TODO Auto-generated method stub
- super.onReceivedTouchIconUrl(view, url, precomposed);
- }
- @Override
- public boolean onCreateWindow(WebView view, boolean isDialog,
- boolean isUserGesture, Message resultMsg) {
- // TODO Auto-generated method stub
- return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
- }
- }
- }
- <uses-permission android:name="android.permission.INTERNET" />
转载请注明出处 http://blog.csdn.net/typename/article/details/39030091 powered by meichal zhao
Android WebView 开发详解(一)的更多相关文章
- Android WebView 开发详解
Android WebView 开发详解 参见 http://blog.csdn.net/typename/article/details/39030091
- Android WebView 开发详解(三)
转载请注明出处 http://blog.csdn.net/typename/article/details/40302351 powered by miechal zhao 概览 Android ...
- Android WebView 开发详解(二)
转载请注明出处 http://blog.csdn.net/typename/article/details/39495409 powered by miechal zhao 概览: Androi ...
- JMessage Android 端开发详解
目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 IM 应用会需要有哪些功能? 用户注册 / 登 ...
- Android USB 开发详解
Android USB 开发详解 先附上 Android USB 官方文档 Android通过两种模式支持各种 USB 外设和 Android USB 附件(实现Android附件协议的硬件):USB ...
- 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句
本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...
- Android Widget 开发详解(二) +支持listView滑动的widget
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/47027263 不少开发项目中都会有widget功能,别小瞧了它,他也是androi ...
- 【转】【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9057257 由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字 ...
- 【Android应用开发详解】实现第三方授权登录、分享以及获取用户资料
由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个Demo.实现起来的效果还是不错的,不敢独享,决定写一个总结的教程,供大家互相 ...
随机推荐
- Android开发之闹钟
闹钟开发: 1.需要时间选择器TimePicker 2.需要Calendar类对日期时间进行操作 3.需要AlarmManager//闹钟管理实质是一个全局定时器, 是Android中常用的一种系统级 ...
- PowerDesigner使用教程 —— 概念数据模型 (转)
一.概念数据模型概述 概念数据模型也称信息模型,它以实体-联系(Entity-RelationShip,简称E-R)理论为基础,并对这一理论进行了扩充.它从用户的观点出发对信息进行建模,主要用于 ...
- iOS开发——图片轮播图+单选选项
由于公司开发需要,需要滚动每道评测题, 并且一道评测题单项选择,按钮和文字都可点击选中 (单选比多选复杂一点,但是原理差不多) 1.当初任务紧,代码也没有优化,仅供思路参考,先放几张图 2.代码部分 ...
- 【html】【7】基础布局初探
当了解了上面的文章有一定基础后,开始尝试初步基础布局,可能不美观,但是要开始有布局框架思想 基础代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- 关于C++对汉字拼音的处理——终结篇(补充)
需要补充的有三个方面: 1.新华字典数据获取方法1: 点击这里 2.新华字典数据获取方法2: 点击这里 3.比较稳定的其它的汉字转拼音的方法: 点击这里 *注:由于内容较多3个部分分文3篇博客进行分别 ...
- LevelDb原理剖析
在说LevelDb之前,先认识两位大牛,Jeff Dean和Sanjay Ghemawat,这两位是Google公司重量级的工程师,为数甚少的Google Fellow之二. Jeff Dean其人: ...
- 盗链网易163、腾讯QQ、新浪sina、百度Baidu的图片之PHP独立版
网易相册频道,网易相册确实是一个高质量图片的地方,而且免费,唯一缺点是很多加了水印,但这个不重要了,无意间发现网易163相册频道的图片是防止盗链的,于是便自己写了一个小程序来突破这个. 本盗链图片最新 ...
- Starting MySQL.. ERROR! The server quit without updating PID file (/usr/local/mysql/data/localhost.localdomain.pid).
[root@localhost ~]# cd /usr/local/mysql [root@localhost mysql]# chown -R mysql.mysql . [root@loc ...
- 折腾了一早上的C# WPF ListView+Grid 实现图片+文字 自动换行排列 类似Windows资源管理器效果
<ListBox Name="lstFileManager" Background ="Transparent" ItemsSource="{B ...
- hdu 5510 Bazinga KMP+尺取法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 题意:至多50组数据,每组数据至多500个字符串,每个字符串的长度最长为2000.问最大的下标( ...