Android框架学习笔记03Retrofit框架
来源:互联网 发布:淘宝信用查询网 编辑:程序博客网 时间:2024/04/30 18:29
前面我们学习过了Android网络开发中的Okhttp框架和Asynchttpclient框架,这一篇我们学习一个非常强大的框架——Retrofit框架。Retrofit现在最新版本是2.1.0,Retrofit框架是Square公司推出来的,是在Okhttp基础上的进一步封装。
在这里对Okhttp做一些说明:Okhttp是基于HTTP协议封装的,跟HttpClient、HttpUrlConnection的职责是一样的,虽然Okhttp也可以开线程,但它是更多偏向于真正的网络通信。Okhttp是基于NIO和OKio的,这里可能很多人不明白什么是IO、NIO和Okio,这里做一个简单的解释:IO和NIO是Java的概念,IO是一种阻塞式的数据读取,举个例子:我向网络中请求数据,程序就一种在等待,等到网络中返回数据并解析好了,程序才往下执行,这种就是阻塞式的;而NIO则是非阻塞式的,还是刚才那个例子,向网络请求数据,但是程序继续执行,等到数据返回和处理完才通知我,然后通过回调处理,这种就是非阻塞式的,非阻塞式的效率比阻塞式的高。而Okio是Square公司在IO和NIO基础上封装的一个更高效、更简单的数据处理库。
下面我们介绍一下Retrofit这个框架
概述
Retrofit框架是基于Okhttp封装的,在1.0版本的时候是默认采用Okhttp通信,不过在没有添加Okhttp依赖的时候也可以采用自带的网络请求通信,解析数据方式是Gson(一个Google推出的Json数据解析框架,后面我们会介绍),所以我们需要添加Gson的依赖。但是在2.0后的版本中,Retrofit是必须要采用Okhttp请求,还有请求返回数据的解析也不是Gson,需要我们自己手动指定。
Retrofit是通过注解将HTTP请求转化为Java接口,那么,我们了解一下Retrofit提供有哪些注解?
请求方式的注解
- DELETE:构建一个DELETE请求
- GET:构建一个GET请求
- HTTP:可以代替其它的任意一种
- OPTIONS:构建一个OPTIONS请求
- PATCH:构建一个PATCH请求
- POST:构建一个POST请求
- PUT:构建一个PUT请求
上面列出的都是Retrofit2.0提供的网络请求方式的注解,其中,我们可以通过HTTP这个注解自定义一个请求方式,例如:
interface Service { @HTTP(method = "CUSTOM", path = "custom/endpoint/") Call<ResponseBody> customEndpoint(); }
甚至HTTP注解也可以用于发送一个DELETE请求方式的请求体,例如:
interface Service { @HTTP(method = "DELETE", path = "remove/", hasBody = true) Call<ResponseBody> deleteObject(@Body RequestBody object); }
标记注解
- FormUrlEncoded注解:与@Field或者@FieldMap一起使用,上传表单数据
- Multipart注解:与@Part一起使用
- Streaming注解:用于下载大文件
参数注解
- Body注解::用于POST请求体,将实例对象根据转换方式转换为对应的json字符串参数,这个转化方式是GsonConverterFactory定义的。
Field注解:@Field和@FormURLEncoded一起使用,表示提交一个表单数据给服务器,我们都知道,表单数据是以键值对的形式存在,所以,@Field注解中的参数字符串为“键”,而被@Field标注的参数值为 “值”,例如:
@FormUrlEncoded @POST("/list") Call<ResponseBody> example(@Field("name") String... names);
FieldMap注解:这个注解跟上面的@Field注解差不多,也是和@FieldURLEncoded一起使用。注解的是一个Map,键作为表单数据的”键”,值作为表单数据的”值”,例如
@FormUrlEncoded@POST("/things")Call<ResponseBody> things(@FieldMap Map<String, String> fields);
Part注解:与@PartMap一样
PartMap注解:用于POST文件上传,其中@Part MultipartBody.Part代表文件,@Part(“key”)RequestBody代表参数,需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data,例如:
@Multipart@POST("/upload")Call<ResponseBody> upload(@Part("file") RequestBody file,@PartMap Map<String, RequestBody> params);
Query注解:表示查询参数,非常简单
- QueryMap注解:查询参数,用于GET查询,需要注意的是@QueryMap可以约定是否需要encode
其它注解
Path注解:URL占位符,我们看一个例子:
@GET("/image/{id}")Call<ResponseBody> example(@Path("id") int id);@GET("/user/{name}")Call<ResponseBody> encoded(@Path("name") String name);就是将例子中用@Path标注的参数用来替换服务器地址中使用“{}”括起来的字符串,简单说就是,这是一个占位符。但是注意的是,不能替换URL中的字符串,例如:在http://www.hitomis.com/user.do?action=findUser&username="zuck"中,不能替换action=findUser&username="zuck"路径中的内容
Url注解:使用全路径复写baseUrl,用于不是同一baseUrl的场景
Header注解:设置请求头,可以不设置。设置的话就是@Header里面注解参数为”键”,被@Header注解的参数作为”值”,例如:
@GET("/")Call<ResponseBody> foo(@Header("Accept-Language") String lang);
Headers注解:用于修饰方法,用于设置多个Header值
- HeaderMap注解:与Header类似
好了,Retrofit就简单介绍到这里,下面我们还是学习一下怎么使用这个框架!
使用
Android Studio使用需要在Gradle中添加依赖,建议先去GitHub上获取最新的依赖,在这里给出Retrofit的GitHub地址和官网地址:
GItHub地址:https://github.com/square/retrofit
官网地址:http://square.github.io/retrofit/
compile 'com.squareup.retrofit2:retrofit:2.1.0'
这是Gradle依赖,我们需要用到java/Json转换器工厂,所以需要添加转换器的依赖,可以直接在AS里面搜索最新,包括上面的Retrofit依赖也可以在AS里面搜索
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
如果你想用RxJava支持的适配器的话,需要添加适配器的依赖,也可以直接在AS里面搜索,这里我们没有用到,所以就不需要添加支持RxJava适配器的依赖。
简单描述一下使用Retrofit框架的基本步骤:
第一步当然就是添加依赖了,Android开发的话基本都是用Gradle的,如果是Java可以用Maven。
第二步则是定义一些接口,Retrofit是面向接口编程的。
第三步是创建Retrofit对象,一般是使用Builder模式创建这个对象
第四步就是使用Retrofit。
上面列出的就是使用Retrofit的基本步骤,下面我们具体使用一下这个强大的网络请求框架
我们说过Retrofit是面向接口编程的,所以使用之前我们需要定义一些我们用到的接口,那么我们先看一下我们定义的接口:
package com.example.frame.common;import com.example.frame.bean.ContributorsBean;import java.util.List;import okhttp3.MultipartBody;import okhttp3.ResponseBody;import retrofit2.Call;import retrofit2.http.Field;import retrofit2.http.FormUrlEncoded;import retrofit2.http.GET;import retrofit2.http.Multipart;import retrofit2.http.POST;import retrofit2.http.Part;import retrofit2.http.Query;import retrofit2.http.Url;/** * Created by :Huawen * Created time : 2016/9/22 16:15 * Description : * Github: https://github.com/Devin1102 */public interface RetrofitAPI {/** * 普通的请求 * * @return */@GET("repos/square/retrofit/contributors")Call<List<ContributorsBean>> getData();/** * 查询 * * @param username * @return */@GET("sayHello")Call<ResponseBody> getQuery(@Query("username") String username);/** * 上传文件 * * @param fileUrl * @return */@GETCall<ResponseBody> downloadFiel(@Url String fileUrl);/** * 上传文件 * * @param description * @param file * @return */@Multipart@POST("upload")Call<ResponseBody> uploadFile(@Part("description") ResponseBody description, @Part MultipartBody.Part file);/** * 上传表单数据 * * @param username * @param password * @return */@FormUrlEncoded@POST("sayHello")Call<ResponseBody> postForm(@Field("username") String username, @Field("password") String password);}
除了接口之外,我们还将Retrofit对象的获取封装了,看一下封装的代码:
public class RetrofitService { protected Retrofit getRetrofit() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(UrlUtils.GET_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); return retrofit; } public RetrofitAPI createRetrofitAPI() { return getRetrofit().create(RetrofitAPI.class); }}
这里也没有什么好解析,我们这里没有添加OkhttpClient端,Retrofit会自动创建一个,当然我们也可以自己手动设置一个。
使用Retrofit实现简单的GET请求
使用Retrofit框架完成GET请求非常简单,我们先看一下代码:
private void retrofitGet() { Call<List<ContributorsBean>> call = mRetrofit.getData(); call.enqueue(new Callback<List<ContributorsBean>>() { @Override public void onResponse(Call<List<ContributorsBean>> call, Response<List<ContributorsBean>> response) { Log.i(TAG, "onResponse请求成功"); List<ContributorsBean> beans = response.body(); for (ContributorsBean contributorsBen : beans) { Log.i(TAG, "onResponse" + contributorsBen); } } @Override public void onFailure(Call<List<ContributorsBean>> call, Throwable t) { Log.i(TAG, "onFailure请求失败"); } });}
这里对应的接口里面的GET请求,里面我们没有设置参数。这种请求跟Okhttp框架请求方式差不多,使用的也是异步的请求。
Retrofit实现Query参数请求
这个是一个简单的GET请求,不过设置一些参数,上面我们说过@Query和@QueryMap是用于GET请求的设置参数,我们看一下具体的代码:
private void retrofitGetQuery() { Call<ResponseBody> call = mRetrofit.getQuery("Devin"); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.i(TAG, getResources().getString(R.string.req_success)); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.i(TAG, getResources().getString(R.string.req_failed)); } });}
这里我们设置一个参数,与接口一致。
Retrofit实现POST上传表单数据
我们在做实际项目的时候,需要向服务器传递一些表单数据,比如登录、注册功能的时候,Retrofit也给我们提供了实现表单数据上传的方法,我们看一下具体的例子:
private void retrofitPostForm() { Call<ResponseBody> call = mRetrofit.postForm("Devin", "Devin"); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.i(TAG, getResources().getString(R.string.req_success)); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.i(TAG, getResources().getString(R.string.req_failed)); } });}
设置表单数据上传的时候需要在接口中设置@FormUrlEncoded这个方法标记,通过@Field或者@FieldMap实现设置数据。
Retrofit实现文件下载
文件下载是经常使用的网络操作,比如图片和视频下载、APP更新等。我们看一下Retrofit框架提供的文件下载功能:
private void retrofitDownloadFile() { Call<ResponseBody> call = mRetrofit.downloadFiel("http://repo1.maven.org/maven2/com/squareup/retrofit2/retrofit/2.1.0/retrofit-2.1.0.jar"); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { InputStream is = response.body().byteStream(); try { FileOutputStream fos = new FileOutputStream(new File("/sdcard/retrofit-2.1.0.jar")); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { fos.write(bytes, 0, len); } fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.i(TAG, "onResponse" + getResources().getString(R.string.req_success)); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.i(TAG, "onFailure" + getResources().getString(R.string.req_failed)); } });}
在定义文件下载接口的时候,我们设置了@Url参数,这个是复写BaseUrl的,用于我们不使用baseUrl的情况,里面被@Url标志的数据是字符串类型,就是文件下载的URL。然后下载成功之后,以读流的形式将文件保存起来。
Retrofit实现文件上传
文件上传也是经常使用的功能,我们看一下Retrofit框架实现文件上传的功能:
private void retrofitUploadFile() { String descriptionString = "UploadFile"; ResponseBody description = ResponseBody.create(MediaType.parse("multipart/form-data"), descriptionString); RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), new File("/sdcard/retrofit-2.1.0.jar")); MultipartBody.Part body = MultipartBody.Part.createFormData("picture", "retrofit-2.1.0.jar", requestFile); Call<ResponseBody> call = mRetrofit.uploadFile(description, body); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { Log.i(TAG, "onResponse" + getResources().getString(R.string.req_success)); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.i(TAG, "onFailure" + getResources().getString(R.string.req_failed)); } });}
文件上传需要在接口中设置@Multipart标记,在接口中我们设置了两个参数:@Part(“description”) ResponseBody description, @Part MultipartBody.Part file,我们需要构建两个参数,然后实现上传。
以上是我对Retrofit框架的基本理解和具体的使用,可能写法不是很好,如果大家有更好的写法,欢迎大家留言交流。
上面Demo已经上传到GitHub了,当然还有其它框架的使用Demo,Demo的GitHub地址:https://github.com/Devin1102/AndroidFrameDemo
- Android框架学习笔记03Retrofit框架
- Android框架Retrofit 2.0学习笔记
- Android开发笔记之retrofit网络框架
- Retrofit框架使用笔记
- Retrofit框架笔记01
- Retrofit框架笔记02
- Android 网络框架学习之Retrofit
- Android 网络框架学习之Retrofit,androidretrofit
- Android 网络框架学习之Retrofit
- Android 网络框架学习之Retrofit
- Android 网络框架学习之Retrofit
- Android 网络框架学习之Retrofit,androidretrofit
- android 网络框架学习(okhttp,retrofit,rxjava)
- Android学习和使用Retrofit框架
- Android框架学习之Retrofit(一)
- retrofit框架学习
- Android Retrofit框架解析
- Android Retrofit框架解析
- MongoDB基础部分及实现(二)
- 第四周项目5-多项式求和
- http的一个在线工具(推荐)
- Qt之QStringListModel
- RDLC 使用经验谈
- Android框架学习笔记03Retrofit框架
- Mac下ZooKeeper环境部署,Linux方法相同
- 2016ACM/ICPC Shengyang Online-1002 List wants to travel
- Cygwin安装和配置
- 超高清视频体验-4K片源
- Xcode8 创建NSManageObject subclass方法
- QT之QTableWidget
- freemarker单问号,双问号,感叹号的用法
- Android动画(链接好文)