android 多么好用的retrofit
来源:互联网 发布:dm软件 编辑:程序博客网 时间:2024/06/13 09:30
retrofit简介
retrofit来源
retrofit是大名鼎鼎的Square公司开源的一个优秀的库,用来简化网络请求的,其中的有点不由分说,结合mvp模式使用更是会让你爱不释手。
什么是mvp模式?点击mvp模式介绍retrofit优点
★ Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂。定义网络业务接口Retrofit的网络请求都是写在一个接口中,并使用一定的注释如下面一组请求接口:注意接口中的每个方法的参数都需要使用标注,不采用标注将会报错。
```/** * Created by melo on 2017/3/6. * 定义数据接口 */public interface Api { @GET(UrlConfig.VIDEO) Call<VideoBean> getVideoData(); @POST("{path}?") Call<HotBean> getHotData(@Path("path") String path, @QueryMap() Map<String, String> map);}```
★ Retrofit使用简单,结构层次分明,每一步都能清晰的表达出之所以要使用的寓意
★ Retrofit支持同步和异步执行,使得请求变得异常简单,只要调用enqueue/execute即可完成
★ Retrofit更大自由度的支持我们自定义的业务逻辑,如自定义Converters
★ Retrofit简化了网络请求流程,同时自己内部对OkHtttp客户端做了封装,同时2.x把之前1.x版本的部分不恰当职责都转移给OkHttp了(例如Log,目前用OkHttp的Interceptor来实现),这样的好处是职责清晰,Retrofit做自己该做的事儿。
★ Retrofit提供不同的Json Converter实现(也可以自定义),同时提供RxJava支持(返回Observable对象),配合Jackson(或者Gson)和RxJava,再加上Dagger2,你的效率至少可以提高一倍。
retrofit请求参数注解类型
- @Query、@QueryMap
@GET("type/actor") Call<VideoBean> getVideoData(@Query("year") String y); //这样做相当于url为 type/actor?year=y @POST("{path}?") Call<HotBean> getHotData(@Path("path") String path, @QueryMap() Map<String, String> map); //假设map 内为 键值对key=a value=A ,key=b value=B , //这样做相当于url为path?a =A&b =B
- @Field
//Post方式传递参数,同时在方法上添加@FormUrlEncoded,即以表单的方式传递参数.这里假 设获取注册用户 @FormUrlEncoded @POST("resigeruser/message") Call<ResigerUser> getResigerMsg(@Field("type") String allUsers);
- @Path
//就是url中的一个替代符号,比如这个api,全是妹子哦http://gank.io/api/data/福利/10/1 //解释下这个链接 福利对应类型type 10 对应每页返回的条数 1表示页码,就可以表示成 @GET("{type}/{amount}/{page}") Call<List<User>> groupList(@Path("type") String type , @Path("amount") String amount , @Path("page") String page,); //如果还时不理解,不妨去试一试,就有体会了
- @Part
//用于文件上传,另外需要同时在方法上添加@Multipart,比如注册用户上传的头像 @Multipart @PUT("resigeruser/headportrait ") Call<ResigerUser> submitHeadPortrait (@Part("headportrait ") RequestBody headportrait , @Part("description") RequestBody description);
- @Header 和@Headers 就是单个头部和多个头部的意思,下面会有使用到。
retrofit使用
▲get请求
- 第一步在module中配置bulid.gradle
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.3.1' //okhttp+retrofit compile 'com.squareup.okhttp3:okhttp:3.5.0' compile 'com.squareup.retrofit2:retrofit:2.0.2' //gson compile 'com.squareup.retrofit2:converter-gson:2.0.2'}
添加依赖okhttp包和retrofit包,另外需要添加converter-gson包,retrofit的优点中已经介绍过这点,所以这个是不可缺少的。
2. 第二步定义retrofit访问的Api接口类
/** * Created by melo on 2017/3/6. * 定义数据接口 */public interface Api { @GET(UrlConfig.SHEHUI) Call<ShehuiBean> getString();}
可以清楚的看到上面的注解@GET就是用get请求的方式,返回的是一个ShehuiBean类型的结果
3. 第三步编写RetrofitHelper类
/** * Created by melo on 2017/3/6. * 定义retrofit类 */public class RetrofitHelper { private static volatile RetrofitHelper instance = null; private RetrofitHelper() { } //创建单例 public static RetrofitHelper getInstance() { if (instance == null) { synchronized (RetrofitHelper.class) { if (instance == null) { instance = new RetrofitHelper(); } } } return instance; } //创建OkHttpClient 对象 public OkHttpClient createHttpClient() { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(60 * 1000, TimeUnit.MILLISECONDS) .readTimeout(60 * 1000, TimeUnit.MILLISECONDS) .build(); return client; }//创建Retrofit 对象 public Retrofit createRetrofit() { return new Retrofit.Builder() .baseUrl(UrlConfig.BASE_URL) .client(createHttpClient()) //gson解析要加 .addConverterFactory(GsonConverterFactory.create(createGson())) //rxjava 需要添加 //.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); }//创建Api 对象 public Api getService() { Retrofit retrofit = createRetrofit(); Api apiService = retrofit.create(Api.class); return apiService; } /** * @return */ public Gson createGson() { return new GsonBuilder() .serializeNulls() .enableComplexMapKeySerialization()// .setDateFormat("") .create(); }}
这个类中的方法就不用多说了
4. 最后再看我们的MainActivity代码也不多
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RetrofitHelper.getInstance().getService().getString().enqueue(new Callback<ShehuiBean>() { @Override public void onResponse(Call<ShehuiBean> call, Response<ShehuiBean> response) { if (response.isSuccessful()){ ShehuiBean shehuiBean= response.body(); Log.i("tag",shehuiBean.getTitle()); } } @Override public void onFailure(Call<ShehuiBean> call, Throwable t) { Log.i("tag","下载失败"); } }); }}
这里用了enqueue异步请求,以为耗时操作基本都是异步调度的嘛
这是基本的get请求
▲ post请求
post请求 和get在请求方式上的不同之处在于post将各种参数都放在包体中,这样做自然就是比较安全,不至于想get方式一样请求参数都暴露在外部
接下来看我们如何操作的呢
- 第一步,在Api接口类中增加post请求方法
/** * Created by melo on 2017/3/6. * 定义数据接口 */public interface Api { @GET(UrlConfig.SHEHUI) Call<ShehuiBean> getString(); @POST("{path}?") Call<GuoNeiBean> getGuoNeiData(@Path("path") String path, @QueryMap() Map<String, String> map);}
对于请求体不确定的参数赢{}?的方式,比如如下链接http://v.juhe.cn/toutiao/index?type=guonei&key=723060051cc0b5baa348a8024b1bb7e1
此处的index页码是不确定的,就可以用上述方式改造。
2. 第二步直接就可以去请求网络了,先看代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //社会 get请求 RetrofitHelper.getInstance().getService().getString().enqueue(new Callback<ShehuiBean>() { @Override public void onResponse(Call<ShehuiBean> call, Response<ShehuiBean> response) { if (response.isSuccessful()){ ShehuiBean shehuiBean = response.body(); Log.i("tag", "社会:" +shehuiBean.getResult().getData().get(0).getTitle()); } } @Override public void onFailure(Call<ShehuiBean> call, Throwable t) { Log.i("tag","下载失败"); } }); //国内 post请求 HashMap<String, String> map = new HashMap<>(); map.put("type", "guonei"); map.put("key", "723060051cc0b5baa348a8024b1bb7e1"); RetrofitHelper.getInstance().getService().getGuoNeiData(UrlConfig.GUONEI,map).enqueue(new Callback<GuoNeiBean>() { @Override public void onResponse(Call<GuoNeiBean> call, Response<GuoNeiBean> response) { if (response.isSuccessful()) { GuoNeiBean guoNeiBean = response.body(); Log.i("tag", "国内:" + guoNeiBean.getResult().getData().get(0).getTitle()); } } @Override public void onFailure(Call<GuoNeiBean> call, Throwable t) { } }); }}
可以看到我们用map将所请求的参数以键值对的形式装了起来,还可以通过传入页面index去控制所要下载的数据
▲ 上传图片
这里先留着吧,因为我自己没有搭建本地的服务,后面有机会在补充
想了解这部分点击此处
拦截器???
以上两种请求都是基本的用法,但是一般项目中post请求除了键值对,也还会遇到json、xml的请求,后台也做了约束,约束其上传格式为json/xml,防止乱入,一般会需要添加头文件headers
方式一:在Api接口类的方法中注解添加
public interface Api { @GET(UrlConfig.SHEHUI) Call<ShehuiBean> getString(); @Headers({"Content-Length:200","Content-type:application/json",})//分别为 请求内容长度限制,请求限制为json格式 @POST("{path}?") Call<GuoNeiBean> getGuoNeiData(@Path("path") String path, @QueryMap() Map<String, String> map);}
上述添加的请求头不一定在此处合适,但是用法雷同。
方式二:添加拦截器,在拦截器内添加header,便于统一管理
/** * Created by melo on 2017/8/9. * header拦截器 */public class NetInterceptor implements Interceptor{ @Override public Response intercept(Chain chain) throws IOException { Request.Builder builder = chain.request().newBuilder(); Request requst = builder.addHeader("Content-type", "application/json") .addHeader("Content-Length","300") .build(); return chain.proceed(requst); }}
至于需要增加什么样的限制,继续addHeader就可以。
接下来就需要修改RetrofitHelper中Httpclient的构建
public OkHttpClient createHttpClient() { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(60 * 1000, TimeUnit.MILLISECONDS) .readTimeout(60 * 1000, TimeUnit.MILLISECONDS) //添加拦截器 .addInterceptor(new NetInterceptor()) .build(); return client; }
然后去掉Api中刚才方式一添加的Headers就可以了,Api方法中就可以用Body体去传json类型的bean类了(此处不能直接在方法内传string类型的字符串哦,需自行体会)
github:demo链接
- android 多么好用的retrofit
- 多么好的领悟
- 师徒制,多么好的工具
- Okhttp, Retrofit, android-async-http, Volley用哪个好
- Okhttp, Retrofit, android-async-http, Volley用哪个好
- 【Android】Retrofit的使用(1)-Retrofit介绍
- 保持淡定的心态,理解好基础知识是多么的重要
- 准备工作多么的重要
- 多么痛的感悟
- 多么暧昧的句子
- 多么痛的领悟
- 多么痛的领悟。。。
- 能吹是多么的重要
- 多么痛的领悟
- 多么痛的领悟
- 多么痛的领悟!!!
- 心情很不好!昨天刚发工资才知道混是多么的不容易。
- 最近标杆型自媒体程苓峰发文章说自己的广告效果多么好
- 结构体存储方式
- react-router 4.x(路由)
- JS学习-方法
- Node.js 中产生随机数的方法
- HTTP的长连接和短连接(转)
- android 多么好用的retrofit
- 《reinforcement learning:an introduction》第十章《On-policy Control with Approximation》总结
- HDU 6092 Rikka with Subset 【dp多重背包】【好题】
- TCP/IP详解学习笔记(2)-数据链路层
- javaScript浏览器兼容性问题大汇总
- 【精】ACM
- DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
- 练习3
- 安装pip