android webview使用记录
来源:互联网 发布:类似于知乎的网站 编辑:程序博客网 时间:2024/06/08 14:42
webview的使用场景挺多的,比如说一些临时性质的活动,直接使用webview来做,效果更快,而且不用更新客户端。等等。
本地文件用:webView.loadUrl(file:///android_asset/XXX.html);这里的格式是固定的,文件位置 assets目录下
LOAD_DEFAULT: 默认缓存规则: 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
判断网络要加上权限<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
上面的代码处理了接收错误的情况。
上面的代码会显示一个进度条,交互更加友好。
开始直接webView.destory(),发现会报
如果发现链接里面是有login?这个字段的,可以支持跳转到客户端已经支持的页面去,我写的demo里面是跳到用户登录页面。
1 webview的基本使用
使用webview,首先要加上权限:<uses-permission android:name="android.permission.INTERNET"/>,否则会在webiew上报找不到对应的链接。
1.1 基本加载网页:
网络用:webView.loadUrl("http://www.baidu.com");本地文件用:webView.loadUrl(file:///android_asset/XXX.html);这里的格式是固定的,文件位置 assets目录下
1.2 网页缓存模式:
LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据LOAD_DEFAULT: 默认缓存规则: 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
如:www.taobao.com的cache-control为no-cache,在模式LOAD_DEFAULT下,无论如何都会从网络上取数据,如果没有网络,就会出现错误页面;
在LOAD_CACHE_ELSE_NETWORK模式下,无论是否有网络,只要本地有缓存,都使用缓存。本地没有缓存时才从网络上获取。www.360.com.cn的cache-control为max-age=60,在两种模式下都使用本地缓存数据。
总结:根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK。if (isNetworkConnected(webActivity.this)) {wSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);} else {wSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);}public boolean isNetworkConnected(Context context) {if (context != null) {ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();if (mNetworkInfo != null) {return mNetworkInfo.isAvailable();}}return false;}
判断网络要加上权限<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1.3 goBcak canGoBack goForward canGoForward
这个是在后退的时候,不直接退出,而是返回到上一个页面,知道无法后退。
@OnClick(R.id.btn_left)void goBack() {if (webView.canGoBack()) {webView.goBack();} else {btn_left.setEnabled(true);}}@OnClick(R.id.btn_right)void goForward() {if (webView.canGoForward()) {webView.goForward();} else {btn_right.setEnabled(true);}}@InjectView(R.id.btn_exit)Button btn_exit;@OnClick(R.id.btn_exit)void exit() {finish();}@OnClick(R.id.btn_refresh)void goRefresh() {webView.reload();}
2 WebViewClient 和 WebChromeClient 区别
WebView主要负责解析渲染,WebViewClient 和WebChromeClient是用来辅助WebView。
2.1 WebViewClient
setWebClient就是帮助WebView处理各种通知、请求事件。
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
webView.setWebViewClient(new WebViewClient() {public void onReceivedError(WebView view, int errorCode,String description, String failingUrl) { // Handle the errorToast.makeText(getApplicationContext(), "网络连接失败 ,请连接网络。",Toast.LENGTH_SHORT).show();}});
上面的代码处理了接收错误的情况。
2.2 WebChromeClient
setWebChromeClient辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等。
webView.setWebChromeClient(new WebChromeClient() {@Overridepublic void onProgressChanged(WebView view, int newProgress) {if (newProgress == 100) {progressbar.setVisibility(View.GONE);} else {if (progressbar.getVisibility() == View.GONE) {progressbar.setVisibility(View.VISIBLE);}progressbar.setProgress(newProgress);}super.onProgressChanged(view, newProgress);}});
3 WebView页面中播放了音频,退出Activity后音频仍然在播放
自己在做的时候看到别人提到这点,就做了一个实验。打开百度音乐,播放音乐,然后退出,果然仍然在播放。
/** * 防止音频,视频结束后仍然播放!,Error: WebView.destroy() called while still attached! */@Overrideprotected void onDestroy() {super.onDestroy();if (webView != null) {parentlayout.removeView(webView);webView.removeAllViews();webView.destroy();}}
开始直接webView.destory(),发现会报
WebView.destroy() called while still attached!
这个错误,需要在destory之前把webView从父容器中删除。
4 webview支持定位
这个是对接了一个网站,人家支持web定位,我这边没做。运营报给我的错误。
首先加上权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
添加对应的代码:
wSettings.setDatabaseEnabled(true);String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();// 启用地理定位wSettings.setGeolocationEnabled(true);// 设置定位的数据库路径wSettings.setGeolocationDatabasePath(dir);// 开启DomStorage缓存wSettings.setDomStorageEnabled(true);//配置权限(同样在WebChromeClient中实现) public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); super.onGeolocationPermissionsShowPrompt(origin, callback); }
5 webview跳转到之前已经完成的功能
在一个大的Android项目中,由于客户端来不及更新和实现,经常会内嵌一些网页(在一些大型的互联网公司,PC的产品总是跑在客户端的前面),比如活动页面,通常可以内嵌用html5实现的页面,可以适配手机。但是这些网页中有好多链接,但是这些链接有些内容有是我们客户端已经实现的,比如有一个注册链接,其实客户端也实现了注册功能,我们不想再继续跳转到网页注册,而是打开客户端某个注册Activity,可以通过以下方式来实现
webView.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// TODO Auto-generated method stub// view.loadUrl(url);if (url != null && url.contains("login?")) {Map<String, String> mapRequest = UrlUtils.URLRequest(url);String userId = mapRequest.get("userid");if (!StringUtils.textIsNull(userId)) {Intent i = new Intent(webActivity.this,LoginActivity.class);Bundle bundle = new Bundle();bundle.putString("userID", String.valueOf(userId));i.putExtras(bundle);startActivity(i);finish();}return true;}return super.shouldOverrideUrlLoading(view, url);}
6 js和原生交互
这个是我之前在做sdk开发的时候遇到的问题,也总结到这个里面把。
首先如果您在编写HTML5应用,需要在JS代码中访问Java中的函数,则您会用到WebView的addJavascriptInterface()函数。因为安全问题,在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有 @JavascriptInterface注解的Java函数。
之前,任何Public的函数都可以在JS代码中访问,而Java对象继承关系会导致很多Public的函数都可以在JS中访问,其中一个重要的函数就是 getClass()。然后JS可以通过反射来访问其他一些内容。通过引入 @JavascriptInterface注解,则在JS中只能访问 @JavascriptInterface注解的函数。这样就可以增强安全性。
如果您的应用android:targetSdkVersion数值为17或者大于17记得添加 @JavascriptInterface 注解。
之前,任何Public的函数都可以在JS代码中访问,而Java对象继承关系会导致很多Public的函数都可以在JS中访问,其中一个重要的函数就是 getClass()。然后JS可以通过反射来访问其他一些内容。通过引入 @JavascriptInterface注解,则在JS中只能访问 @JavascriptInterface注解的函数。这样就可以增强安全性。
如果您的应用android:targetSdkVersion数值为17或者大于17记得添加 @JavascriptInterface 注解。
// 网页中包含JavaScript内容需调用以下方法,参数为truewSettings.setJavaScriptEnabled(true);webView.addJavascriptInterface(new JsObject(), "demo");final class JsObject {@JavascriptInterfacepublic void clickOnAndroid() {mHandler.post(new Runnable() {@SuppressLint("JavascriptInterface")public void run() {webView.loadUrl("javascript:wave()");}});}}
对于的网页,我放在assets下面
<html> <script > function wave() { document.getElementById("android").src="android_waving.png"; } </script> <body> <a onClick="window.demo.clickOnAndroid()"> <img id="android" src="ic_launcher.png" mce_src="ic_launcher.png"/><br> Click me! </a> <br/> <br/> <a href="http://test/login?userId=1234">login</a> </body> </html>
webview需要加进一个回调的代理类JsObject,并给它一个调用的名称:demo
js调用java方法
<a onClick="window.demo.clickOnAndroid()">
Java要调用js的方法,只需知道js的方法名称即可:
上面的例子显示出来了js调用java方法,然后java调用了js的方法,更换了图片。webView.loadUrl("javascript:wave()");
7 安全的js
https://github.com/pedant/safe-java-js-webview-bridge大家可以看下github的demo,我试了一下,对应的jsObject方法必须是static,感觉不太好使,网上没有具体的使用例子。
butterknife 配置参考:http://blog.csdn.net/hlllmr1314/article/details/36375273?utm_source=tuicool
demo地址:http://download.csdn.net/detail/jjdhshdahhdd/9056235
1 0
- android webview使用记录
- 记录使用Android WebView碰到的问题
- Android使用WebView的一些记录
- Android WebView记录
- WebView的使用记录
- android 关于使用webView的一些问题记录
- WebView--- Android WebView使用总结
- Android WebView填坑记录
- android webview 常用设置 - 记录
- Android WebView填坑记录
- 记录Android webView 的一点点
- Android WebView填坑记录
- Android WebView的使用
- android WebView使用
- Android WebView的使用
- Android WebView使用
- Android-----WebView使用
- Android-----WebView使用
- pthread_create函数的详细讲解(包括向线程函数传递参数详解)
- DataStructure-8.1-二叉排序树
- 个人小结
- 【读书笔记】iOS-头文件导入-@class注意事项
- Oracle常用知识点记录
- android webview使用记录
- Apache开启mod_deflate压缩网页后输出
- 每天工作计划
- [C++11 并发编程] 14 关联任务与期望
- JSONUtils 工具类
- AOJ 2534 Dictionary
- 学习JS(7)
- strstr函数的自己实现
- 6天通吃树结构—— 第五天 Trie树