WebView详解及使用说明;(android外壳项目总结版)
2016-07-20 13:43
501 查看
最近做了一个关于webview写安卓的壳,套HTML5的应用,虽然整个写下来后,到了目前的进度,代码量不多,共有1000多行,但是整个壳的设计思想和实现思路还是当初查了很久的。所以写下来,以备后续查看和分享。
这个webview的壳目前实现的功能我将从三方面说明并总结。
1. 最基本的功能:
增加useragent以便HTML5判断出是哪个应用
设置webSetting缓存
拦截url并将相应网络资源替换成本地资源
javascript和android交互
2. 增加用户体验的功能:
网络状态监听
HTML进度条替换成Android原生进度条,以及onPageFinished中遇到的坑
3. 我们的应用需要增加的额外功能:
口语评测打分
下载资源包并在本地解压,本地MP3的播放、暂停以及退出并返回当前的播放进度。
本地录音并存储为PCM格式,本地PCM的播放
消息推送功能
下面进行详细说明:
最基本的功能
增加useragent以便HTML5判断出是哪个应用(android或者ios)(这里的android_agent和HTML商量好就可以)
设置webSettting缓存
我们原来的想法是将图片、css、js、son、plain、vtt等一些不变的文件下载到本地,然后通过拦截替换url进行网络资源替换成本地资源,但是后来发现webSetting缓存其实webView这个控件自己以及做的比较完善了,所以就用了webSetting自带的缓存,我们只需要进行一些webSetting的函数设置就可以了。
拦截url并将相应网络资源替换成本地资源
我们将一些固定不变的图片放到工程的assets文件下,然后拦截网络的url进行替换,这样用户在第一次进入界面时,就不会因为加载图片而花费较长时间,造成用户体验不好,但是如果拦截到相应的的url时间长了,页面依旧会加载比较长的时间,但这个Android就无能为力了。
拦截替换函数如下:
虽然看着代码很多,但是其实有用的只有 WebResourceResponse response = null;以及response = new WebResourceResponse("text/vtt", "UTF-8", fin);这两句
js和android交互
android调用js的代码
其中DM.progress是HTML的方法,percent是android需要传过去的参数,其他为固定内容。
js调用android的代码方法:
JsToJava()是android里面自己写的类,这个类中所有的函数都可以被JS以window.record.XX(); 方式调用,其中XX是函数名。需要特别注意的是XX函数上要添加@SuppressLint("JavascriptInterface"),否则调用会无响应
2.增加用户体验的功能
网络状态的监听
这个功能用了一个广播监听,动态注册或解绑广播,提示信息显示方式用了SnackBar(Material Design中的控件)
HTML进度条替换成Android原生进度条,以及onPageFinished中遇到的坑
由于android将资源替换成本地的了,因此相应的进度条也要替换成android的,由android端来控制什么时候加载完成,按正常来说,onPageFinished在被调用时,该界面就已经加载完成了,但是实际操作中发现,onPageFinished被调用的时候,界面并没有被加载完成,还有一部分web的进度条会显示,因此我们在onPageFinished函数中执行了延迟函数
然后在onPageFinished函数中进行调用即可
3.我们的应用需要增加的额外功能
口语评测打分,采用的科大讯飞语音打分的技术,具体请点开超链接,参考文档。
下载资源包并在本地解压,本地MP3的播放、暂停以及退出并返回当前的播放进度。这里需要说明的是,下载资源包使用的是OKHttpUtils
消息推送功能,集成的是友盟的推送。
暂时功能模块如上所述,如果有更新新功能,还会回头来补充这篇文章。
这个webview的壳目前实现的功能我将从三方面说明并总结。
1. 最基本的功能:
增加useragent以便HTML5判断出是哪个应用
设置webSetting缓存
拦截url并将相应网络资源替换成本地资源
javascript和android交互
2. 增加用户体验的功能:
网络状态监听
HTML进度条替换成Android原生进度条,以及onPageFinished中遇到的坑
3. 我们的应用需要增加的额外功能:
口语评测打分
下载资源包并在本地解压,本地MP3的播放、暂停以及退出并返回当前的播放进度。
本地录音并存储为PCM格式,本地PCM的播放
消息推送功能
下面进行详细说明:
最基本的功能
增加useragent以便HTML5判断出是哪个应用(android或者ios)(这里的android_agent和HTML商量好就可以)
WebSettings webSettings = webView.getSettings(); String ua = webSettings.getUserAgentString(); webSettings.setUserAgentString(ua + getString(R.string.android_agent));
设置webSettting缓存
我们原来的想法是将图片、css、js、son、plain、vtt等一些不变的文件下载到本地,然后通过拦截替换url进行网络资源替换成本地资源,但是后来发现webSetting缓存其实webView这个控件自己以及做的比较完善了,所以就用了webSetting自带的缓存,我们只需要进行一些webSetting的函数设置就可以了。
拦截url并将相应网络资源替换成本地资源
我们将一些固定不变的图片放到工程的assets文件下,然后拦截网络的url进行替换,这样用户在第一次进入界面时,就不会因为加载图片而花费较长时间,造成用户体验不好,但是如果拦截到相应的的url时间长了,页面依旧会加载比较长的时间,但这个Android就无能为力了。
拦截替换函数如下:
webView.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d("start", url); } @Override public void onLoadResource(WebView view, String url) { Log.e("cache", "onLoadResource-url=" + url); super.onLoadResource(view, url); } public WebResourceResponse shouldInterceptRequest(WebView view, String url) { WebResourceResponse response = null; Log.d("Webview", "shouldInterceptRequest url=" + url); if (url.contains("ajax.php") && !Validate.isNetworkConnected(Webview.this)) { //网络连接不可用时并且拦截到ajax时 } if (url.contains("http://emodou.com/resource/be")) { //三种中的第一种,替换资源文件 String path = url.substring(17, url.length()); File file = new File(Constants.STORAGE_URL_START + path);//path: /resource/be/e_Res/BF1/22101/res/1.jpg Log.d("path", path); FileInputStream fin = null; try { fin = new FileInputStream(file); //进行"/"分割 String[] urlArray = url.split("/"); int urlCount = urlArray.length; Log.d("count", urlCount + ""); //进行"."分割 String suffixes = urlArray[urlCount - 1]; String[] suffixesArray = suffixes.split("\\."); int suCount = suffixesArray.length; //如果遇到后缀名符合的,进行拦截替换 if (suffixesArray[suCount - 1].equals("jpg") || suffixesArray[suCount - 1].equals("png") || suffixesArray[suCount - 1].equals("jpeg") || suffixesArray[suCount - 1].equals("JPG") || suffixesArray[suCount - 1].equals("PNG") || suffixesArray[suCount - 1].equals("JPEG")) { response = new WebResourceResponse("image/png", "UTF-8", fin); } else if (suffixesArray[suCount - 1].equals("mp3") || suffixesArray[suCount - 1].equals("MP3")) { response = new WebResourceResponse("audio/mpeg", "UTF-8", fin);//mp3替换不到 } else if (suffixesArray[suCount - 1].equals("JSON") || suffixesArray[suCount - 1].equals("json")) { response = new WebResourceResponse("application/json", "UTF-8", fin); } else if (suffixesArray[suCount - 1].equals("lrc") || suffixesArray[suCount - 1].equals("LRC")) { response = new WebResourceResponse("text/plain", "UTF-8", fin); } else if (suffixesArray[suCount - 1].equals("mp4") || suffixesArray[suCount - 1].equals("MP4")) { response = new WebResourceResponse("video/mp4", "UTF-8", fin); } else if (suffixesArray[suCount - 1].equals("vtt") || suffixesArray[suCount - 1].equals("VTT")) { response = new WebResourceResponse("text/vtt", "UTF-8", fin); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } } return response; } });
虽然看着代码很多,但是其实有用的只有 WebResourceResponse response = null;以及response = new WebResourceResponse("text/vtt", "UTF-8", fin);这两句
js和android交互
android调用js的代码
webView.loadUrl("javascript:DM.progress("+percent+")");
其中DM.progress是HTML的方法,percent是android需要传过去的参数,其他为固定内容。
js调用android的代码方法:
webView.addJavascriptInterface(new JsToJava(), "record");
JsToJava()是android里面自己写的类,这个类中所有的函数都可以被JS以window.record.XX(); 方式调用,其中XX是函数名。需要特别注意的是XX函数上要添加@SuppressLint("JavascriptInterface"),否则调用会无响应
@SuppressLint("JavascriptInterface") public void initWebView() {
}
2.增加用户体验的功能
网络状态的监听
这个功能用了一个广播监听,动态注册或解绑广播,提示信息显示方式用了SnackBar(Material Design中的控件)
HTML进度条替换成Android原生进度条,以及onPageFinished中遇到的坑
由于android将资源替换成本地的了,因此相应的进度条也要替换成android的,由android端来控制什么时候加载完成,按正常来说,onPageFinished在被调用时,该界面就已经加载完成了,但是实际操作中发现,onPageFinished被调用的时候,界面并没有被加载完成,还有一部分web的进度条会显示,因此我们在onPageFinished函数中执行了延迟函数
public class TimeControlTask extends AsyncTask { @Override protected void onPostExecute(String s) { super.onPostExecute(s); av.setVisibility(View.GONE); webView.setVisibility(View.VISIBLE); } @Override protected String doInBackground(Integer... params) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } }
然后在onPageFinished函数中进行调用即可
new TimeControlTask().execute();
3.我们的应用需要增加的额外功能
口语评测打分,采用的科大讯飞语音打分的技术,具体请点开超链接,参考文档。
下载资源包并在本地解压,本地MP3的播放、暂停以及退出并返回当前的播放进度。这里需要说明的是,下载资源包使用的是OKHttpUtils
消息推送功能,集成的是友盟的推送。
暂时功能模块如上所述,如果有更新新功能,还会回头来补充这篇文章。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories