分类: Android开源框架哪点事2013-09-02 14:25 260人阅读 评论(0) 收藏 举报

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(){
@Override
public void onLoading(long count, long current) {
textView.setText(current+"/"+count);
} @Override
public 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=5255
cause = 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;
else
throw 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第一篇——揭开圣女的面纱的更多相关文章

  1. Android 开源框架Universal-Image-Loader完全解析(三)---源代码解读

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/39057201),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  2. Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  3. Android 开源框架Universal-Image-Loader全然解析(二)--- 图片缓存策略具体解释

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  4. Android开源框架ViewPageIndicator和ViewPager实现Tab导航

    前言: 关于使用ViewPageIndicator和ViewPager实现Tab导航,在开发社区里已经有一堆的博客对其进行了介绍,假设我还在这里写怎样去实现.那简直就是老生常谈,毫无新奇感,并且.我也 ...

  5. android 开源框架推荐

    同事整理的 android 开源框架,个个都堪称经典.32 个赞! 1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1)  JS ...

  6. Android开源框架ViewPagerIndicator的基本使用

    转载本博客请注明出处:点击打开链接    http://blog.csdn.net/qq_32059827/article/details/52495647 很多新闻资讯类的app都有一些共性,那就是 ...

  7. 六款值得推荐的Android开源框架简介

    技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的“性价比”比较高的Android开源框架,应该是相对实用的. 1.volley 项目地址 https://github.com/smanik ...

  8. Android——开源框架Universal-Image-Loader + Fragment使用+轮播广告

    原文地址: Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析(二) ...

  9. Android 开源框架Universal-Image-Loader学习

    Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析(二)--- 图片 ...

随机推荐

  1. NodeMCU学习(二) : 如何使用NodeMCU进行开发

    NodeMCU的GPIO口 Arduino的引脚号与NodeMCU的GPIO口直接对应,NodeMCU的GPIO函数pinMode,  digitalWrite, DigitalRead也是和Ardu ...

  2. 网站每日PV/IP统计/总带宽/URL统计脚本分享(依据网站访问日志)

    在平时的运维工作中,我们运维人员需要清楚自己网站每天的总访问量.总带宽.ip统计和url统计等.虽然网站已经在服务商那里做了CDN加速,所以网站流量压力都在前方CDN层了像每日PV,带宽,ip统计等数 ...

  3. 分布式监控系统Zabbix-3.0.3-完整安装记录 - 添加shell脚本监控

    对公司的jira访问状态进行监控,当访问状态返回值是200的时候,脚本执行结果为1:其他访问状态返回值,脚本执行结果是0.然后将该脚本放在zabbix进行监控,当非200状态时发出报警.jira访问状 ...

  4. 结构化分析(SA)

    1.什么叫模型?我觉得它的关键字:抽象 重要特征 降低复杂度. 2.软件设计的方法 分类:面向功能~,面向对象的设计. 面向数据流的方法是在结构化分析中提到的. 哦~ 3.面向数据流的结构化分析 特点 ...

  5. ASP.NET Forms验证

    /// <summary> /// 执行用户登录操作 /// </summary> /// <param name="config">授权配置信 ...

  6. 七牛云域名DV SSL证书申请流程以及CDN融合加速配置

    从2017年起,苹果ios以及微信小程序都陆续要求请求连接request地址是使用HTTPS协议的.所以在项目开发阶段就要考虑解决https的问题,同时这也是为项目实际安全所考虑.最近我也是在折腾项目 ...

  7. vue路由异步组件案例

    最近研究了vue性能优化,涉及到vue异步组件.一番研究得出如下的解决方案. 原理:利用webpack对代码进行分割是异步调用组件前提.异步组件在优先级上让位同步组件.下面介绍的是怎么实现异步组件. ...

  8. 面象对象设计原则之二:开放封闭原则(Open-Closed Principle, OCP)

    开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则.开闭原则由Bertrand  Meyer于1988年提出,其定义如下: 开闭原则(Open-Closed Principle, ...

  9. Oracle 数据库 Only 导出空表的方法

    1. 之前因为oracle11.2.0.1 的bug(deferred_segment_creation) 引起无法将空表导出. 有时给同事解释上半个小时他们也不知道 如何处理 或者是 他们不会用ex ...

  10. [转载]以及部分总结--Linux下创建单机ASM存储的Oracle实例的过程---感谢方总

    Linux下单机安装ASM流程总结 一.安装Linux ESXi上传iso镜像至存储目录 创建虚拟机,并且选择主机设备的ISO启动 选择完成时编辑虚拟机设置 配置镜像文件如下: 打开控制台: 并且选择 ...