摘要:上一篇中我们介绍了框架的基本使用方法,这一篇我们学习一下的另外一个网络请求框架框架。这里需要实现内部类回调,框架自己有实现有,不需要我们自己手动实现,我们只需要调用即可。其中是可以选择的,没有请求参数可以直接设置为。
上一篇中我们介绍了OkHttp3.0框架的基本使用方法,这一篇我们学习一下Android的另外一个网络请求框架——AsyncHttpClient框架。Asynchttpclient框架是一个开源的异步网络请求框架,所有的网络都在Android的非UI线程中,通过回调方法处理请求结果,无论是向网络请求数据还是上传数据都非常方便,而且这个框架非常体积非常小,只有90K左右的大小,我们可以轻松使用它,下面我们介绍一下这个框架:
概述Asynchttpclient框架有如下的特征:
处理异步Http请求,并通过匿名内部类处理回调结果
Http异步请求均位于非UI线程,不会阻塞UI操作
通过线程池处理并发请求处理文件上传、下载,响应结果自动打包JSON格式
自动处理连接断开时请求重连
永久的cookie保存,内部实现用的是Android的SharedPreferences
通过BaseJsonHttpResponseHandler和各种json库集成
支持SAX解析器
支持各种语言和content编码,不仅仅是UTF-8
自动的gzip响应解码
内置多种形式的响应解析,有原生的字节流,string,json对象,甚至可以将response写到文件中
这里只是简单的介绍一下,具体需要实现细节需要我们在开发中实际去体会。
我们来学习一下Asynchttpclient里面的具体的类:
AsyncHttpRequest类:继承自Runnabler,被submit至线程池执行网络请求并发送start,success等消息
AsyncHttpResponseHandler类:接收请求结果,一般重写onSuccess及onFailure接收请求成功或失败的消息,还有onStart,onFinish等消息
TextHttpResponseHandler类:继承自AsyncHttpResponseHandler,只是重写了AsyncHttpResponseHandler的onSuccess和onFailure方法,将请求结果由byte数组转换为String
JsonHttpResponseHandler类:继承自TextHttpResponseHandler,同样是重写onSuccess和onFailure方法,将请求结果由String转换为JSONObject或JSONArray
BaseJsonHttpResponseHandler类:继承自TextHttpResponseHandler,是一个泛型类,提供了parseResponse方法,子类需要提供实现,将请求结果解析成需要的类型,子类可以灵活地使用解析方法,可以直接原始解析,使用gson等
RequestParams类:请求参数,可以添加普通的字符串参数,并可添加File,InputStream上传文件
AsyncHttpClient类:核心类,使用HttpClient执行网络请求,提供了get,put,post,delete,head等请求方法,使用起来很简单,只需以url及RequestParams调用相应的方法即可,还可以选择性地传入Context,用于取消Content相关的请求,同时必须提供ResponseHandlerInterface(AsyncHttpResponseHandler继承自ResponseHandlerInterface)的实现类,一般为AsyncHttpResponseHandler的子类,AsyncHttpClient内部有一个线程池,当使用AsyncHttpClient执行网络请求时,最终都会调用sendRequest方法,在这个方法内部将请求参数封装成AsyncHttpRequest(继承自Runnable)交由内部的线程池执行
SyncHttpClient类:继承自AsyncHttpClient,同步执行网络请求,AsyncHttpClient把请求封装成AsyncHttpRequest后提交至线程池,SyncHttpClient把请求封装成AsyncHttpRequest后直接调用它的run方法
这里就不介绍里面的方法了,具体的可以去Github看一下源码:https://github.com/loopj/android-async-http
或者可以看一下API:https://loopj.com/android-async-http/doc/
再简单介绍一下Asynchttpclient框架的请求流程:
首先调用AsyncHttpClient的get或post等方法发起网络请求
所有的请求都走了sendRequest,在sendRequest中把请求封装为了AsyncHttpRequest,并添加到线程池执行
当请求被执行时(即AsyncHttpRequest的run方法),执行AsyncHttpRequest的makeRequestWithRetries方法执行实际的请求,当请求失败时可以重试。并在请求开始,结束,成功或失败时向请求时传的ResponseHandlerInterface实例发送消息
基本上使用的都是AsyncHttpResponseHandler的子类,调用其onStart,onSuccess等方法返回请求结果
关于Asynchttpclient就简单介绍到这里,下面介绍一下Asynchttpclient的具体使用
使用Asynchttpclient框架的使用步骤基本是:
创建一个AsyncHttpClient对象
通过RequestParams对象设置请求参数,这个是可选择的
调用AsyncHttpClient对象里面的方法,实现请求或者上传数据。这里需要实现内部类回调,框架自己有实现有,不需要我们自己手动实现,我们只需要调用即可。
如果是在Android Studio中使用,需要在gradle中添加:
compile "com.loopj.android:android-async-http:1.4.9"
如果是Eclipse的话需要去GitHub或者官网下载相应版本的JAR吧,GitHub地址在上文中有给出,下面是Asynchttpclient的官网:http://loopj.com/android-async-http/
下面看一下具体的代码:
AsyncHttpClient client = new AsyncHttpClient(); client.get("https://www.google.com", new AsyncHttpResponseHandler() { @Override public void onStart() { // called before request is started } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { // called when response HTTP status is "200 OK" } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { // called when response HTTP status is "4XX" (eg. 401, 403, 404) } @Override public void onRetry(int retryNo) { // called when request is retried } });
这里是Get请求的写法,官方推荐我们使用静态的写法:
import com.loopj.android.http.*; public class TwitterRestClient { private static final String BASE_URL = "https://api.twitter.com/1/"; private static AsyncHttpClient client = new AsyncHttpClient(); public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { client.get(getAbsoluteUrl(url), params, responseHandler); } public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { client.post(getAbsoluteUrl(url), params, responseHandler); } private static String getAbsoluteUrl(String relativeUrl) { return BASE_URL + relativeUrl; } }
这样方便我们使用。
下面我们使用这个框架实现GET请求、POST请求、文件上传、文件下载这四个功能,这里没有实现保存Cookie的功能,有需要的可以扩展实现:
实现GET请求我们先看一下具体实现的代码:
AsyncHttpUtils.get(UrlUtils.REQUEST_URL + UrlUtils.URL_KEY, null, new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, JSONObject response) { super.onSuccess(statusCode, headers, response); Log.i(TAG, getResources().getString(R.string.req_success)); Log.i(TAG, "======================================================================"); Log.i(TAG, response.toString()); Log.i(TAG, "======================================================================"); } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) { super.onFailure(statusCode, headers, throwable, errorResponse); Log.i(TAG, getResources().getString(R.string.req_failed)); } });
这样就可以实现一个GET请求,请求是在非UI线程中,有请求成功的回调和请求失败的回调,我们更新UI需要通过发消息或者其它方式实现,不能再请求成功的回调方法里面直接更新UI。其中RequestParams是可以选择的,没有请求参数可以直接设置为null。非常简单,就不在做过多的介绍了。
实现POST请求我们还是先看一下具体的代码:
RequestParams requestParams = new RequestParams(); requestParams.put("username", "Devin"); requestParams.put("password", "Devin"); AsyncHttpUtils.post(UrlUtils.POST_URL, requestParams, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { Log.i(TAG, getResources().getString(R.string.req_success)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { Log.i(TAG, getResources().getString(R.string.req_failed)); } });
POST请求需要上传一些参数,框架提供了设置参数的类RequestParams,其中,RequestParams类似于Map,是键值对的形式,添加请求参数有三种方式:
第一种就是像我上面代码一样,创建一个空的RequestParams对象,然后通过put方法将参数写入;
第二种则是创建的时候就直接添加,例如:
RequestParams params = new RequestParams("single", "value");
第三种是将参数写入一个Map中,然后将Map赋给RequestParams,例如:
HashMapparamMap = new HashMap (); paramMap.put("key", "value"); RequestParams params = new RequestParams(paramMap);
这三种方式无论哪一种都可以实现封装请求参数。
实现文件上传使用Asynchttpclient实现文件上传也非常简单,我们先看一下代码:
RequestParams requestParams = new RequestParams(); File file = new File("/sdcard/okhttp-3.4.1.jar"); try { requestParams.put("file", file); AsyncHttpUtils.post(UrlUtils.UPLOAD_URL, requestParams, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { Log.i(TAG, getResources().getString(R.string.req_success)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { Log.i(TAG, getResources().getString(R.string.req_failed)); } }); } catch (FileNotFoundException e) { e.printStackTrace(); }
可以看到,这里文件上传是将文件封装到RequestParams中的,Asynchttpclient框架提供的封装文件到RequestParams中有三种方法,分别是:
第一种是将文件转成流的形式封装到RequestParams中,例如:
InputStream myInputStream = blah; RequestParams params = new RequestParams(); params.put("secret_passwords", myInputStream, "passwords.txt");
第二种就是像上面的代码一样,将文件直接封装到RequestParams中
第三种是将文件转成二进制数组的形式,例如:
byte[] myByteArray = blah; RequestParams params = new RequestParams(); params.put("soundtrack", new ByteArrayInputStream(myByteArray), "she-wolf.mp3");
这三种方法无论哪一种都可以实现封装文件到RequestParams中,然后调用AsyncHttpClient对象中的方法实现上传,具体使用哪一种看个人喜欢了。
实现文件下载使用Asynchttpclient框架实现文件下载也非常简单,我们先看一下代码:
AsyncHttpUtils.download(UrlUtils.DOWNLOAD_URL, null, new FileAsyncHttpResponseHandler(getActivity()) { @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) { Log.i(TAG, getResources().getString(R.string.req_failed)); } @Override public void onSuccess(int statusCode, Header[] headers, File file) { Log.i(TAG, getResources().getString(R.string.req_success)); } });
实现文件下载,回调选择的就是FileAsyncHttpResponseHandler这个Asynchttpclient框架提供的类,这可以非常方便的实现文件的下载。
关于Asynchttpclient框架就简单介绍到这里了,还有保存Cookie这个功能没有实现,不过实现也非常简单,不懂得可以看一下官方的文档,官网地址上文中有给出了。
文中Demo已经上传到GitHub中,有兴趣的可以去了解一下:https://github.com/Devin1102/AndroidFrameDemo
最后,欢迎留言交流学习!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65163.html
摘要:杨充一定时间内该点击事件只能执行一次用来修饰这是一个什么类型的注解。杨充自定义编译器获取遍历,并生成代码配置文件文件配置的作用是向系统注册自定义注解处理器,执行编译时使用进行处理。 目录介绍 01.创建项目步骤 1.1 项目搭建 1.2 项目功能 02.自定义注解 03.创建Processor 04.compiler配置文件 05.编译jar 06.如何使用 07.编译生成代...
摘要:动画占用大量内存,如何优化使用动画的注意事项有哪些问题这个问题主要出现在帧动画中,当图片数量较多且图片较大时就极易出现,这个在实际开发中要尤其注意,尽量避免使用帧动画。 目录介绍 4.0.0.1 Android中有哪几种类型的动画,属性动画和补间动画有何区别?补间动画和属性动画常用的有哪些? 4.0.0.2 View动画为何不能真正改变View的位置?而属性动画为何可以?属性动画是如...
阅读 3233·2021-11-18 10:02
阅读 1935·2021-09-22 10:54
阅读 2988·2019-08-30 15:43
阅读 2575·2019-08-30 13:22
阅读 1574·2019-08-29 13:57
阅读 1040·2019-08-29 13:27
阅读 731·2019-08-26 14:05
阅读 2511·2019-08-26 13:30