Android WebView 开发详解(一)
转载请注明出处 http://blog.csdn.net/typename/article/details/39030091powered 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
- WebViewwebview=newWebView(this);
- setContentView(webview);
(2)在xml中配置WebView
[html] view plain copy
- <Webview
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- </Webview>
[html] view plain copy
- webview.loadUrl("http://developer.android.com/");
2.WebView API使用详解
1)请求加载网页部分 [java] view plain copy- publicvoidloadData(Stringdata,StringmimeType,Stringencoding)
加载指定的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
- publicvoidloadDataWithBaseURL(StringbaseUrl,Stringdata,StringmimeType,Stringencoding,StringhistoryUrl)
[java] view plain copy
- publicvoidloadUrl(Stringurl)
[java] view plain copy
- publicvoidloadUrl(Stringurl,Map<String,String>additionalHttpHeaders)
加载制定url并携带http header数据。
[java] view plain copy
- publicvoidreload()
重新加载页面
Tip(重要)
页面所有资源会重新加载
[java] view plain copy
- publicvoidstopLoading()
2) 前进后退
[java] view plain copy
- publicvoidgoBack()
- publicvoidgoForward()
- publicvoidgoBackOrForward(intsteps)
[java] view plain copy
- publicbooleancanGoForward()
- publicbooleancanGoBack()
3)JavaScript操作
[java] view plain copy
- publicvoidaddJavascriptInterface(Objectobject,Stringname)
当网页需要和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
- classJsObject{
- @JavascriptInterface
- publicStringtoString(){return"injectedObject";}
- }
- webView.addJavascriptInterface(newJsObject(),"injectedObject");
[java] view plain copy
- publicvoidevaluateJavascript(Stringscript,ValueCallback<String>resultCallback)
Tips(重要)
这个方法必须在UI线程调用,这个函数的回调也会在UI线程执行。
那么在Android4.4一下如何执行javascrit代码呢
可以通过 WebView提供的loadUrl方法:具体格式如下:
[java] view plain copy
- webView.loadUrl("javascript:alert(injectedObject.toString())");
其中javascript: 是执行javascript代码的标识 , 后面是javascript语句。
[java] view plain copy
- publicvoidremoveJavascriptInterface(Stringname)
4)网页查找功能
[java] view plain copy
- publicintfindAll(Stringfind)
这个API还存在bug 具体请见我的之前一篇博文Android WebView findAll bug
[java] view plain copy
- publicvoidfindAllAsync(Stringfind)
[java] view plain copy
- publicvoidfindNext(booleanforward)
使用example:
[java] view plain copy
- publicclassTestFindListenerimplementsandroid.webkit.WebView.FindListener{
- privateFindListenermFindListener;
- publicTestFindListener(FindListenerfindListener){
- mFindListener=findListener;
- }
- @Override
- publicvoidonFindResultReceived(intactiveMatchOrdinal,intnumberOfMatches,
- booleanisDoneCounting){
- mFindListener.onFindResultReceived(activeMatchOrdinal,numberOfMatches,isDoneCounting);
- }
- }
- publicvoidfindAllAsync(StringsearchString){
- if(android.os.Build.VERSION_CODES.JELLY_BEAN<=Build.VERSION.SDK_INT)
- mWebView.findAllAsync(searchString);
- else{
- intnumber=mWebView.findAll(searchString);
- if(mIKFindListener!=null)
- mIKFindListener.onFindResultReceived(number);
- fixedFindAllHighLight();//参见我之前一篇博文AndroidWebViewAPIfindAllbug
- }
- }
- mWebView.findNext(forward);
5)数据清除部分
[java] view plain copy
- publicvoidclearCache(booleanincludeDiskFiles)
[java] view plain copy
- publicvoidclearFormData()
[java] view plain copy
- publicvoidclearHistory()
[java] view plain copy
- publicvoidclearMatches()
[java] view plain copy
- publicvoidclearView()
6)WebView的状态
[java] view plain copy
- publicvoidonResume()
[java] view plain copy
- publicvoidonPause()
[java] view plain copy
- publicvoidpauseTimers()
当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
[java] view plain copy
- publicvoidresumeTimers()
[java] view plain copy
- publicvoiddestroy()
这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。
7) WebView 事件回调监听
[java] view plain copy
- publicvoidsetWebChromeClient(WebChromeClientclient)
[java] view plain copy
- publicvoidsetWebViewClient(WebViewClientclient)
8) Android 5.0 Lollipop 新API
public static voidenableSlowWholeDocumentDraw()
Android 5.0 Webview默认提供减少内存占用支持,并且智能选择需要绘制的HTML document部门来提供性能。 当然开发者可以在自己应用程序需要时关闭这个选项(enableSlowWholeDocumentDraw)。
3. WebView Demo
[java] view plain copy- packagecom.example.webviewdemo;
- importandroid.annotation.SuppressLint;
- importandroid.app.Activity;
- importandroid.content.Context;
- importandroid.graphics.Bitmap;
- importandroid.os.Message;
- importandroid.webkit.WebChromeClient;
- importandroid.webkit.WebSettings;
- importandroid.webkit.WebView;
- importandroid.webkit.WebViewClient;
- publicclassWebViewBaseextendsWebView{
- privatestaticfinalStringDEFAULT_URL="http://www.ijinshan.com/";
- privateActivitymActivity;
- publicWebViewBase(Contextcontext){
- super(context);
- mActivity=(Activity)context;
- init(context);
- }
- @SuppressLint("SetJavaScriptEnabled")
- privatevoidinit(Contextcontext){
- WebSettingswebSettings=this.getSettings();
- webSettings.setJavaScriptEnabled(true);
- webSettings.setSupportZoom(true);
- //webSettings.setUseWideViewPort(true);
- this.setWebViewClient(mWebViewClientBase);
- this.setWebChromeClient(mWebChromeClientBase);
- this.loadUrl(DEFAULT_URL);
- this.onResume();
- }
- privateWebViewClientBasemWebViewClientBase=newWebViewClientBase();
- privateclassWebViewClientBaseextendsWebViewClient{
- @Override
- publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
- //TODOAuto-generatedmethodstub
- returnsuper.shouldOverrideUrlLoading(view,url);
- }
- @Override
- publicvoidonPageStarted(WebViewview,Stringurl,Bitmapfavicon){
- //TODOAuto-generatedmethodstub
- super.onPageStarted(view,url,favicon);
- }
- @Override
- publicvoidonPageFinished(WebViewview,Stringurl){
- //TODOAuto-generatedmethodstub
- super.onPageFinished(view,url);
- }
- @Override
- publicvoidonReceivedError(WebViewview,interrorCode,
- Stringdescription,StringfailingUrl){
- //TODOAuto-generatedmethodstub
- super.onReceivedError(view,errorCode,description,failingUrl);
- }
- @Override
- publicvoiddoUpdateVisitedHistory(WebViewview,Stringurl,
- booleanisReload){
- //TODOAuto-generatedmethodstub
- super.doUpdateVisitedHistory(view,url,isReload);
- }
- }
- privateWebChromeClientBasemWebChromeClientBase=newWebChromeClientBase();
- privateclassWebChromeClientBaseextendsWebChromeClient{
- @Override
- publicvoidonProgressChanged(WebViewview,intnewProgress){
- mActivity.setProgress(newProgress*1000);
- }
- @Override
- publicvoidonReceivedTitle(WebViewview,Stringtitle){
- //TODOAuto-generatedmethodstub
- super.onReceivedTitle(view,title);
- }
- @Override
- publicvoidonReceivedTouchIconUrl(WebViewview,Stringurl,
- booleanprecomposed){
- //TODOAuto-generatedmethodstub
- super.onReceivedTouchIconUrl(view,url,precomposed);
- }
- @Override
- publicbooleanonCreateWindow(WebViewview,booleanisDialog,
- booleanisUserGesture,MessageresultMsg){
- //TODOAuto-generatedmethodstub
- returnsuper.onCreateWindow(view,isDialog,isUserGesture,resultMsg);
- }
- }
- }
[html] view plain copy
- <uses-permissionandroid:name="android.permission.INTERNET"/>
转载请注明出处 http://blog.csdn.net/typename/article/details/39030091powered by meichal zhao
更多相关文章
- 知识梳理:Android子线程中更新UI的3种方法
- android中判断当前运行activity名的方法
- 葵花宝典之普及篇 —— HD2 android 各种直刷方法
- android 点击重新加载界面设计
- android中实现view的更新UI有两组方法的问题
- Android加载SD卡目录,文件夹遍历,图片设置,设置文件对应打开方式等
- Android加载字体包及封装
- Android下拉刷新上拉加载控件,对所有View通用!