Android开源框架Afinal第一篇——揭开圣女的面纱
Android开源框架Afinal第一篇——揭开圣女的面纱
Afinal
这是Afinal在github的地址:https://github.com/yangfuhai/afinal
Afinal这个框架主要分4块:
1、FinalDB模块:android中的orm框架,一行代码就可以进行增删改查。支持一对多,多对一等查询。
2、FinalActivity模块:android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。
3、FinalHttp模块:通过httpclient进行封装http数据请求,支持ajax方式加载。
4、FinalBitmap模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。FinalBitmap的内存管理使用lru算法,没有使用弱引用(android2.3以后google已经不建议使用弱引用,android2.3后强行回收软引用和弱引用,详情查看android官方文档),更好的管理bitmap内存。FinalBitmap可以自定义下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器,在imageview显示图片的时候播放动画等(默认是渐变动画显示)。
这里我们先讲FinalHttp模块,这是它的用法:
AjaxParams params = new AjaxParams();params.put("username", "michael yang");params.put("password", "123456");params.put("email", "test@tsz.net");params.put("profile_picture", new File("/mnt/sdcard/pic.jpg")); // 上传文件params.put("profile_picture2", inputStream); // 上传数据流params.put("profile_picture3", new ByteArrayInputStream(bytes)); // 提交字节流FinalHttp fh = new FinalHttp();fh.post("http://www.yangfuhai.com", params, new AjaxCallBack(){@Overridepublic void onLoading(long count, long current) {textView.setText(current+"/"+count);}@Overridepublic void onSuccess(String t) {textView.setText(t==null?"null":t);}});
大家看到了吧,fh.get(baseUrl, params, new AjaxCallBack(){});
这句话的底层就是HttpClient执行HttpGet或者HttpPost请求的一个封装,其中baseUrl+params拼凑起来就是url,而后面的AjaxCallBack就是对HttpClient对http请求得到的一个HttpResponse响应结果的分析回调。
我们来看具体的流程步骤:
第一步:初始化FinalHttp,然后执行get()方法
public void get( String url, AjaxParams params, AjaxCallBack<? extends Object> callBack) {sendRequest(httpClient, httpContext, new HttpGet(getUrlWithQueryString(url, params)), null, callBack);}
第二步:我们看sendRequest()这个方法,这个方法就是把get方法里的参数传递到这个函数,然后发起http请求。
protected <T> void sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, AjaxCallBack<T> ajaxCallBack) {if(contentType != null) {uriRequest.addHeader("Content-Type", contentType);}new HttpHandler<T>(client, httpContext, ajaxCallBack,charset).executeOnExecutor(executor, uriRequest);}
这是一个保护级的方法,其实还是一个马甲,正真执行的还是那个HttpHandler里的exe方法。我们看到这个方法的参数有DefaultHttpClient,这个都不用说了大家都很熟悉,HttpContext就是一个上下文,HttpUriRequest就是一个get,put,delete,post等http请求,然后就是添加头部信息,比如要不要进行压缩,这里貌似用了zip压缩使得传输速率更快,再后面就是回调函数接口,判断请求是否成功失败等。
第三步:进入HttpHandler类,这是一个处理http请求的类。这个类是继承AsyncTask,但是这个AsyncTask类并不是原生的,而是经过作者精心修改的。没有深入去看AsyncTask,大略看了一下,貌似doInBackground这个方法是放进一个线程池里去执行的。这个线程池配置的很精细,就像批量加载图片那个例子,可以只想你个完上一个线程,就马上执行下一个任务。
1.这个类还实现了EntityCallBack回调接口,并且接收了AjaxCallBack这个回调实例。我们先看doInBackground方法。
protected Object doInBackground(Object... params) {if(params!=null && params.length == 3){targetUrl = String.valueOf(params[1]);isResume = (Boolean) params[2];}try {publishProgress(UPDATE_START); // 开始makeRequestWithRetries((HttpUriRequest)params[0]);} catch (IOException e) {publishProgress(UPDATE_FAILURE,e,e.getMessage()); // 结束}return null;}
2.可以看到真正执行的方法是makeRequestWithRetries(HttpUriRequest *)方法,进去看看先
private void makeRequestWithRetries(HttpUriRequest request) throws IOException {if(isResume && targetUrl!= null){File downloadFile = new File(targetUrl);long fileLen = 0;if(downloadFile.isFile() && downloadFile.exists()){fileLen = downloadFile.length();}if(fileLen > 0)request.setHeader("RANGE", "bytes="+fileLen+"-");}boolean retry = true;IOException cause = null;HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();while (retry) {try {if (!isCancelled()) {HttpResponse response = client.execute(request, context);if (!isCancelled()) {handleResponse(response);} }return;} catch (UnknownHostException e) {publishProgress(UPDATE_FAILURE, e,"unknownHostException:can't resolve host");return;} catch (IOException e) {cause = e;retry = retryHandler.retryRequest(cause, ++executionCount,context);} catch (NullPointerException e) {// HttpClient 4.0.x 之前的一个bug// http://code.google.com/p/android/issues/detail?id=5255cause = new IOException("NPE in HttpClient" + e.getMessage());retry = retryHandler.retryRequest(cause, ++executionCount,context);}catch (Exception e) {cause = new IOException("Exception" + e.getMessage());retry = retryHandler.retryRequest(cause, ++executionCount,context);}}if(cause!=null)throw cause;elsethrow new IOException("未知网络错误");}
其中isResume是断点续传标志,targetUrl判断是文件的话就添加文件大小头部信息。retry是遇到错误是否要重试标志,FinalHttp有这个参数配置,可以设置重试次数。然后就是HttpClient执行Http请求获取响应的操作,如果这个过程中UI上的交互有取消操作的话。可以通过isCancelled()这个方法得知从而取消请求。如果请求顺利会得到一个HttpResponse,而处理这个响应结果是handleResponse()方法。
3.这是专门处理响应结果的方法
private void handleResponse(HttpResponse response) {StatusLine status = response.getStatusLine();if (status.getStatusCode() >= 300) {String errorMsg = "response status error code:"+status.getStatusCode();if(status.getStatusCode() == 416 && isResume){errorMsg += " \n maybe you have download complete.";}publishProgress(UPDATE_FAILURE,new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()),errorMsg);} else {try {HttpEntity entity = response.getEntity();Object responseBody = null;if (entity != null) {time = SystemClock.uptimeMillis();if(targetUrl!=null){responseBody = mFileEntityHandler.handleEntity(entity,this,targetUrl,isResume);}else{responseBody = mStrEntityHandler.handleEntity(entity,this,charset);}}publishProgress(UPDATE_SUCCESS,responseBody);} catch (IOException e) {publishProgress(UPDATE_FAILURE,e,e.getMessage());}}}
通过状态码,判断成功后处理得到的HttpEntity。如果这个response是字符串就由StringEntityHandler这个类去解析,如果是文件就是FileEntityHandler解析。得到结果后,就是publishProgress去推送了,这个方法在前面的方法中都看到有被调用。稍微对AsyncTask熟悉的人就知道这个方法将可以触发onProgressUpdate(* value).这个方法就是告诉你执行的进度,AfinalHttp中AjaxCallback中的onSuccess,onFailure等方法就是根据这个来触发的。
private final static int UPDATE_START = 1;private final static int UPDATE_LOADING = 2;private final static int UPDATE_FAILURE = 3;private final static int UPDATE_SUCCESS = 4;
到这里这个过程就完成了。
看到这么多的处理,会觉得这样是不是会更慢。一个网络请求处理的极其复杂,想FinalHttp很多默认的配置和繁杂的处理响应并通知处理进程,其实这样多多少少拖慢了请求的速度。在实际应用尤其感受深切,一遇到网络慢,跨地域幅度大等教为恶劣的网络环境,AFinal就有点显得捉襟见肘了。
由于篇幅限制,这次就讲这么多了。
http://blog.csdn.net/bvin_/article/details/10914197
Android开源框架Afinal第一篇——揭开圣女的面纱相关推荐
- Android开源框架BRVAH由来篇
简书首发:http://www.jianshu.com/p/2c02ca8763c2 为什么会有它? 在无数个加班的夜里,重复的编写着那一个又一个的列表界面,有的要分组,有的要添加广告头部.有的要不同 ...
- android开源框架(转)
Android开源项目第一篇--个性化控件(View)篇 包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Progre ...
- Android——开源框架Universal-Image-Loader + Fragment使用+轮播广告
原文地址: Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析(二) ...
- 六款值得推荐的Android开源框架简介
六款值得推荐的Android开源框架简介 技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的"性价比"比较高的Android开源框架,应该是相对实用的. 1.volley ...
- Android开源框架源码鉴赏:LruCache与DiskLruCache
关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流 ...
- Android开源框架PowerfulViewLibrary——PowerfulEditText的介绍和源码解析
本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请注明出处:http://blog.csdn.net/chay_chan/article/details/63685905 An ...
- 2019年 Android 开源框架 排行榜 TOP 60
2019年 Android 开源框架 排行榜 TOP 50 1.Retrofit 一句话介绍:Retrofit是一款类型安全的网络框架,基于HTTP协议,服务于Android和java语言 上榜理由: ...
- android 测试工具,Android开源项目第四篇:开发及测试工具篇
本文为那些不错的Android开源项目第四篇--开发工具篇,**主要介绍Android开发工具和测试工具相关的开源项目**. Android开源项目系列汇总已完成,包括: 1.Buck faceboo ...
- Android开源框架——图表MPAndroidChart
开源官网:https://github.com/PhilJay/MPAndroidChart Android开源框架--图表MPAndroidChart 特点 配置 图表类型 Demo MPAndro ...
最新文章
- Spring MVC 中自定义视图 @Component 及 配置 多个视图解析器 Excel视图
- php+mysql分库分表的哈希(hash)算法
- http端口_PhpStorm 修改默认端口号63342
- jq之$(“ul li:first-child“)
- 怎么查看计算机的系统内存大小,Windows10系统怎么查看电脑内存大小
- 单元测试(UT)、功能测试(FT)(转)
- 前台发送 ajax 请求到后台传递数组参数
- UnityShader例子:边缘检测
- 远程桌面/远程登陆中强行登陆(他人退出)与切换回话(登陆后切换到上次别的登陆)3389...
- 智能公租房管理系统概要流程
- 测控专业英语复习资料
- 算法与数据结构1800题 树和二叉树
- 【SOT】SiamFC代码笔记
- Web前端工程师需要什么学历
- Blender 插件开发 添加快捷键
- MSP430FR5994LannchPad开发笔记之三:MSP430的IO复用以及如何去获取IO复用功能
- Win10+外接显示器 “未检测到其他显示器”
- 2018天梯赛第一次训练题解和ac代码
- #include<>和#include“ “
- 【数学建模】灰色关联(Matlab代码实现)
热门文章
- 4创建ui显示不出来_4道小学生经典推理题,家长们一道也做不出来,太烧脑了...
- 面试官的几句话,差点让我挂在HTTPS上
- JMeter的编码与HTTP请求
- 地磅称重软件源码_地磅称重软件需求梳理的重要性
- 《白帽子讲web安全》读书笔记
- Simulink中Simscape—Fluids模块(原Simhydraulics)学习记录
- java中选择结构有哪些_Java中的选择结构
- deepin启动盘无法引导安装_deepin 无法启动问题解决
- mysql存储过程返回hello world_Mysql存储过程 之 “Hello,World”
- 零基础入门CV赛事-Task1 赛题理解