WebView详解(一)
来源:互联网 发布:北京学java最好的学校 编辑:程序博客网 时间:2024/06/06 13:22
代码示例地址
前言
WebView一直是安卓的一个大坑,新版本经常会废弃旧版本的api,导致在使用WevView的时候经常会遇到各种各样的问题,在此整理下WebView的用法及一些坑。
一、 WebView介绍
WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。它使用了WebKit渲染引擎加载显示网页。iOS的UIWebView也同样使用的是WebKit内核,不知道为何渲染速度比Android快很多,坑也比Android少。
本章主要包含WebView的简单使用;WebView常用的三个类WebSettings,WebViewClient,WebChromeClient;进度条;在当前WebView中打开新连接,不跳转到系统浏览器;back键返回访问历史;js与原生互调;加载web url,插入本地js。
1、简单的使用
(1)在布局里声明WebView。
<WebView android:id="@+id/mWebView" android:layout_width="match_parent" android:layout_height="match_parent" />
(2)使用loadUrl方法加载网页。
mWebView = (WebView) findViewById(R.id.mWebView);mWebView.loadUrl("http://wujinkui.com/");
二、使用WebView常用到的三个类
1、WebSettings 关于WebView的一些设置,比如缓存,js等
2、WebViewClient 主要帮助WebView处理各种通知、请求事件等
3、WebChromeClient 主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
1、WebSettings
获取WebSettings:WebSettings settings = mWebView.getSettings();
方法:
不是说所有的方法都列出来了,只是一些会用到的,下同
//下面三个最常用,基本都需要设置
setCacheMode 设置缓存的模式 eg: settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
setJavaSciptEnabled 设置是否支持Javascript eg: settings.setJavaScriptEnabled(true);
setDefaultTextEncodingName 设置在解码时使用的默认编码 eg: settings.setDefaultTextEncodingName(“utf-8”);
setAllowFileAccess 启用或禁止WebView访问文件数据
setBlockNetworkImage 是否显示网络图像
setBuiltInZoomControls 设置是否支持缩放
setDefaultFontSize 设置默认的字体大小
setFixedFontFamily 设置固定使用的字体
setLayoutAlgorithm 设置布局方式
setLightTouchEnabled 设置用鼠标激活被选项
setSupportZoom 设置是否支持变焦
2、WebViewClient
设置WebViewClient:mWebView.setWebViewClient(new WebViewClient());
方法:
onPageStarted 网页开始加载
onReceivedError 报告错误信息
onLoadResource 加载指定地址提供的资源
shouldOverrideUrlLoading 控制新的连接在当前WebView中打开
onPageFinished 网页加载完毕,此方法并没有方法名表现的那么美好,调用时机很不确定。如需监听网页加载完成可以使用onProgressChanged,当int progress返回100时表示网页加载完毕。
doUpdate VisitedHistory 更新历史记录
onFormResubmission 应用程序重新请求网页数据
onScaleChanged WebView发生改变
3、WebChromeClient mWebView.setWebViewClient(new WebChromeClient());
方法:
onProgressChanged 加载进度条改变
onJsPrompt 用在解决4.2以下addJavascriptInterface漏洞问题
onCloseWindow 关闭WebView
onCreateWindow 创建WebView
onJsAlert 处理Javascript中的Alert对话框
onJsConfirm处理Javascript中的Confirm对话框
onJsPrompt处理Javascript中的Prompt对话框
onReceivedlcon 网页图标更改
onReceivedTitle 网页Title更改
onRequestFocus WebView显示焦点
onConsoleMessage 在Logcat中输出javascript的日志信息
三、WebView复杂的使用
1、进度条
在WebChromeClient里有onProgressChanged方法,利用此方法可以实现进度条。
(1)布局
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/mWebView" android:layout_width="match_parent" android:layout_height="match_parent" /> <ProgressBar android:id="@+id/mProgressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="3dp" android:layout_gravity="center_vertical" android:max="100" android:progressDrawable="@drawable/progress_bar_web_view" /></RelativeLayout>
(2)重写onProgressChanged方法
mWebView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress == 100) { // 网页加载完成 mProgressBar.setVisibility(View.GONE); } else { // 加载中 mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setProgress(newProgress); } }});
2、在当前WebView中打开新连接,不跳转到系统浏览器
重写WebViewClient的shouldOverrideUrlLoading方法
mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(你想在当前页面打开新连接){ view.loadUrl(url); }else if(在一个新的activity中打开新连接){ Intent intent = new Intent(mContext, NewWebViewActivity.class); intent.putputExtra("URL", url); startActivity(intent); } return true; }});
在Android N中 shouldOverrideUrlLoading(WebView view, String url)被废弃,改为shouldOverrideUrlLoading(WebView view, WebResourceRequest request),我们可以通过request.getUrl()来获取url。
@Overridepublic boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return shouldOverrideUrlLoading(view, request.getUrl().toString());}
3、back键返回访问历史
mWebView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { // 返回键退回 mWebView.goBack(); return true; } else return false; }});
4、js与原生互调
原生调用js方法
准备工作,创建一个test.html文件,在此html中创建一个js方法alertMsg,作用为将java里传来的message弹出。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html> <head> <meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/> <title ng-bind="title">原生与js互调</title> <!-- 下面注释用来演示加载本地js文件 --> <!--<script type="text/javascript" src="file:///android_asset/main.js"></script>--> <script type="text/javascript"> function alertMsg(message) { alert(message) } </script> </head> <body> <p>HTML page load success!</p> <!-- js调用原生的Buttion --> <button type="button" onclick="window.stub.nativeMethod('来至JS的参数');">JS调用原生方法</button> </body></html>
布局文件里写一个Button,点击此Butiton,调用js方法。
findViewById(R.id.btn_call_js_method).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //调用alertMsg方法,并传递参数"来自原生的字符串"。 mWebView.loadUrl("javascript:alertMsg('" + "来自原生的字符串" + "')"); }});
点击后页面显示对话框,内容为“来自原生的字符串”。
js调用原生方法
//stub、nativeMethod可自定义,但在java代码里和html代码里必须一致。mWebView.addJavascriptInterface(new JSCallback(), "stub"); //stub为window.stub.nativeMethod中的stub,为自定义.public class JSCallback { //nativeMethod为window.stub.nativeMethod中的nativeMethod @JavascriptInterface public void nativeMethod(String data) { Toast.makeText(NormalActivity.this, data, Toast.LENGTH_SHORT).show(); }}
5、加载web url,插入本地js
在assets文件夹新建一个alert.js。只有一个方法,接受一个mseesage,并将message弹出。
function aliert(message) { alert(message)}
在onPageFinished方法回调的时候,将此js插入到WebView中。此处有坑,尝试了网上的各种方法,均不能成功,最后在stackoverflow上找到方法。
wvContent.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); injectScriptFile(view, "alert.js"); } //ref http://stackoverflow.com/questions/21552912/android-web-view-inject-local-javascript-file-to-remote-webpage private void injectScriptFile(WebView view, String scriptFile) { InputStream input; try { input = getAssets().open(scriptFile); byte[] buffer = new byte[input.available()]; input.read(buffer); input.close(); String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP); view.loadUrl("javascript:(function() {" + "var parent = document.getElementsByTagName('head').item(0);" + "var script = document.createElement('script');" + "script.type = 'text/javascript';" + // Tell the browser to BASE64-decode the string into your script !!! "script.innerHTML = window.atob('" + encoded + "');" + "parent.appendChild(script)" + "})()"); } catch (IOException e) { e.printStackTrace(); } }});
接下来就和用原生调用js一样了。
- Android WebView(一) WebView详解
- WebView详解(一)
- WebView详解一:打造优雅的WebView
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- Android WebView 开发详解(一)
- WebView开发详解(一)
- Android WebView 开发详解(一)
- Android里WebView详解(一)
- Android WebView 开发详解(一)
- webview 开发详解(一)
- Andrew Ng coursera上的《机器学习》ex1
- android 字符串拼接
- Mysql删除语句
- 微软医疗BI简介
- vim中大小写转换
- WebView详解(一)
- iOS 开发中你是否遇到这些经验问题
- Android 九宫格解锁Demo--Android 进阶之路
- 常用GIT bash 命令一览
- 2016.8.18 C组总结
- Android中facebook与google的第三方接入
- doGet与doPost的区别
- 可伸缩的TextView
- 关于今天装oracle之后用工具链接时的问题