AsyncTask解析(下)——实现自定义AsyncTask网络传输工具类封装
来源:互联网 发布:海奇软件 编辑:程序博客网 时间:2024/05/20 07:53
在上文: AsyncTask解析(上)——原理分析与超简单demo实现中已经对AsyncTask的实现原理以及源码流程进行了一定的分析,相信大家已经基本熟悉了AsyncTask内部实现网络传输的调用顺序以及过程细节,最后还写出了一个比较简单的Demo实践,十分简单易懂相信大家都能很快掌握。
然而那个Demo还是太粗制滥造了,功能太缺乏,很多需要传入的参数也没有写到构参里直接给写死了..
并且在真正的项目实践中,光使用这个简单的Demo是远远不够的,我们需要对它进行更好的封装,扩展它的功能,才能更好地为我们的项目服务。
所以,本文的核心重点是如何去封装出一个AsyncTask工具类,以及如何让AsyncTask变得简单易用。
整体框架的继承关系如下图所示:
理清一下思路,整体框架应用观察者模式,可以细分为以下几个步骤:
1、实现一个抽象类UrlAsyNet继承AsyncTask<String,Integer,T>(这里第三个参数设置为T是为了适配不同的传输类型)。
这里为什么不用接口呢?因为接口的方法是不能有具体的实现的,但是在该方法中需要进行初始化的工作,所以这里使用了抽象类来实现。
/** * Created by nangua on 2016/4/26. * Params 启动任务执行的输入参数,这里是URL所以用String * Progress 后台任务执行的百分比。 * Result 后台执行任务最终返回的结果,比如String。 */public class UrlAsyNet<T> extends AsyncTask<String,Integer,T> { /** * 全部参数构造方法 * @param apikey * @param httpArg * @param httpUrl * @param method * @param onNetStateChangedListener * @param type */ public UrlAsyNet(String apikey, String httpArg, String httpUrl, NetMethod method, OnNetStateChangedListener<T> onNetStateChangedListener, ParamType type) { this.apikey = apikey; this.httpArg = httpArg; this.httpUrl = httpUrl; this.method = method; this.onNetStateChangedListener = onNetStateChangedListener; this.type = type; } /** * 传入URL * @param httpUrl */ public UrlAsyNet(String httpUrl,String apikey,String httpArg) { this.httpUrl = httpUrl; this.apikey = apikey; this.httpArg = httpArg; } //添加枚举类型 public enum NetMethod{ GET,POST } /** * 参数类型。分为:JSONorXML文件。键值对,无参 */ public enum ParamType{ JSON_OR_XML_FILE ,KEY_VALUE_PAIR, NO_PARAM } /** * 网络状态改变时候的监听器 * @param <T> */ public interface OnNetStateChangedListener<T> { /** * 访问网络之前 */ public void beforeAccessNet(); /** * 访问网络成功获取数据之后 * * @param result */ public void afterAccessNet(T result); /** * 出现了错误的时候 */ public void whenException(); /** * 执行进度 * @param progress */ public void onProgress(Integer progress); } //设置监听器回调 public OnNetStateChangedListener<T> getOnNetStateChangedListener() { return onNetStateChangedListener; } //设置网络监听器 public void setOnNetStateChangedListener(OnNetStateChangedListener<T> onNetStateChangedListener) { this.onNetStateChangedListener = onNetStateChangedListener; } //网络监听器实例 OnNetStateChangedListener<T> onNetStateChangedListener; //在四个回调方法中调用网络监听器的方法以实现回调 @Override protected void onCancelled() { if (onNetStateChangedListener!=null){ onNetStateChangedListener.whenException(); } } @Override protected void onPostExecute(T t) { if (onNetStateChangedListener!=null){ onNetStateChangedListener.afterAccessNet(t); } } @Override protected void onPreExecute() { if (onNetStateChangedListener!=null){ onNetStateChangedListener.beforeAccessNet(); } } @Override protected void onProgressUpdate(Integer... values) { if (onNetStateChangedListener!=null){ if (values.length>1) { onNetStateChangedListener.onProgress(values[0]); } } } //使用HttpURLConnection需要用到的httpUrl String httpUrl ; //使用HttpURLConnection需要用到的httpArg String httpArg ; //连接百度API需要的APIKEY String apikey; //得到的参数类型 ParamType type; //网络请求参数(GET或POST) NetMethod method; //数据 String jsonOrXmlFile; //键值对 HashMap<String, Object> keyValuePair; public String getHttpUrl() { return httpUrl; } public void setHttpUrl(String httpUrl) { this.httpUrl = httpUrl; } public String getApikey() { return apikey; } public void setApikey(String apikey) { this.apikey = apikey; } public String getHttpArg() { return httpArg; } public void setHttpArg(String httpArg) { this.httpArg = httpArg; } public ParamType getType() { return type; } public void setType(ParamType type) { this.type = type; } @Override protected T doInBackground(String... params) { return null; } /** * 执行 */ public void execute(){ this.execute(new String[]{}); }}
2、在抽象类里编写一个网络监听器接口。然后在需要使用到的地方(比如在MainActivity里需要使用,就在MainActivity里写一个实现这个接口的内部类,从而在这个内部类里实现随着网络状态的改变改变对UI的操作)。
那么问题来了:这里为什么不把组件当做参数传进去呢?比如在上文中的Demo是把TextView和ProgressBar传进去的,那么如果你要传入的是一个CustView呢?这样就得重新修改写好的代码,拆轮子,违背了程序的可扩展性。所以更好的办法是提供一个可实现的网络监听接口,在接口里进行更新UI操作。
/** * 网络状态改变时候的监听器 * @param <T> */ public interface OnNetStateChangedListener<T> { /** * 访问网络之前 */ public void beforeAccessNet(); /** * 访问网络成功获取数据之后 * * @param result */ public void afterAccessNet(T result); /** * 出现了错误的时候 */ public void whenException(); /** * 执行进度 * @param progress */ public void onProgress(Integer progress); }网络监听器的代码上文已经出现了,这里单独列出来一下。
3、编写具体的工具类UrlNormalAsyNet,实现对数据的接受(暂时没有写JSON和XML的解析):
/** * Created by nangua on 2016/4/26. */public class UrlNormalAsyNet extends UrlAsyNet<String>{ /** * 请求方法POST和get */ AsyNet.NetMethod method; public UrlNormalAsyNet(String apikey, String httpArg, String httpUrl, NetMethod method, OnNetStateChangedListener<String> onNetStateChangedListener, ParamType type) { super(apikey, httpArg, httpUrl, method, onNetStateChangedListener, type); } public UrlNormalAsyNet(String httpUrl, String apikey, String httpArg) { super(httpUrl, apikey, httpArg); this.httpUrl = httpUrl; this.apikey = apikey; this.httpArg = httpArg; } @Override protected String doInBackground(String... params) { BufferedReader reader = null; String result = null; StringBuffer sbf = new StringBuffer(); httpUrl = httpUrl + "?" + httpArg; try { URL url = new URL(httpUrl); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("apikey", apikey); connection.connect(); InputStream is = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); String strRead = null; while ((strRead = reader.readLine()) != null) { sbf.append(strRead); sbf.append("\r\n"); } reader.close(); result = sbf.toString(); if (result != null) { publishProgress(100); } } catch (Exception e) { e.printStackTrace(); } return result; }}
运行截图:
本文暂时更新到这里,以后有时间再继续更新
目标要实现的工具类有三个:UrlFileAsyNet(处理文件网络传输信息),UrlImageAsyNet(处理图片传输信息),UrlNormalAsyNet(处理JSON,XML,或String格式网络传输信息)。
以下是大神同学Dikaros写的完整AsyncTask工具包下载地址:https://github.com/Dikaros/AsyNet
QAQ(づ ̄ 3 ̄)づ求赞求关注!
- AsyncTask解析(下)——实现自定义AsyncTask网络传输工具类封装
- 封装AsyncTask成工具类
- AsyncTask 网络传输
- AsyncTask封装为工具类+Imagerloader
- 封装AsyncTask异步请求网络
- 9、实现自定义AsyncTask
- Android——多线程(AsyncTask封装)
- AsyncTask网络解析-----缓存数据
- android AsyncTask工具类
- AsyncTask工具类
- AsyncTask异步工具类
- AsyncTask 工具类
- AsyncTask工具类--pizifusheng
- AsyncTask 类 解析吧??
- AsyncTask实现下载网络图片
- 通过封装的AsyncTask类实现下载apk应用
- Android源码解析——AsyncTask
- Android源码解析——AsyncTask
- HOG特征
- 关于监听切换应用,app从后台返回进入锁屏界面
- 异常
- 集成融云Android SDK实现在群聊/讨论组中@人的功能(三)
- tortoiseSVN解决冲突
- AsyncTask解析(下)——实现自定义AsyncTask网络传输工具类封装
- js时间戳转日期格式
- iOS运行时与method swizzling
- 移动端调试-charles设置代理,fiddler设置代理,MTL 工具使用,weinre (查看dom元素,查看console.log输出的数据)
- (4.6.11.1)加快Android编译速度:Buck,LayoutCast,JRebel,Jimulabs,Instant Run
- Lsit部分相同项合并,其余相加
- Mysql的Hash索引与B-Tree索引
- Anemometer使用详解
- Android绘制流程