转载请注明出处 http://blog.youkuaiyun.com/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)
- public void loadUrl (String 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)
- 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)
Tips(重要)
这个方法必须在UI线程调用,这个函数的回调也会在UI线程执行。
那么在Android4.4一下如何执行javascrit代码呢
可以通过 WebView提供的loadUrl方法:具体格式如下:
- webView.loadUrl("javascript:alert(injectedObject.toString())");
其中javascript: 是执行javascript代码的标识 , 后面是javascript语句。
- public void removeJavascriptInterface (String name)
4)网页查找功能
- public int findAll (String find)
这个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)
- public void clearFormData ()
- public void clearHistory ()
- public void clearMatches ()
- public void clearView ()
6)WebView的状态
- public void onResume ()
- public void onPause ()
- public void pauseTimers ()
当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
- public void resumeTimers ()
- public void destroy ()
这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。
7) WebView 事件回调监听
- public void setWebChromeClient (WebChromeClient client)
- public void setWebViewClient (WebViewClient client)
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.youkuaiyun.com/typename/article/details/39030091 powered by meichal zhao