android Retrofit2.0RxJava2.0

xiaoxiao2021-02-28  148

android Retrofit2.0

Retrofit 一个用于Android和Java平台的类型安全的网络框架(是一套注解形式的网络请求封装库,REST API协议),Retrofit是一个Square开发的类型安全的REST安卓客户端请求库, 为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。 Retrofit 把REST API返回的数据转化为Java对象,就像ORM框架那样,把数据库内的存储的数据转化为相应的Java bean对象。

REST(Resources Representational State Transfer–资源表现层状态转化)是一组架构约束条件和原则。 RESTful架构都满足以下规则: 1、每一个URI代表一种资源; 2、客户端和服务器之间,传递这种资源的某种表现层(“资源”具体呈现出来的形式,比如.txt,.png,.jpg) ; 3、客户端通过四个HTTP动词(GET用来获取资源,POST用来新建或更新资源,PUT用来更新资源,DELETE用来删除资源),对服务器端资源进行操作,实现”表现层状态转化”。

Retrofit基本用法 1、build.gradle中添加依赖

compile 'com.squareup.okhttp3:okhttp:3.4.1' compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' compile 'com.google.code.gson:gson:2.5' compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.1.0' compile 'io.reactivex.rxjava2:rxjava:2.0.1' compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

2、创建接口、声明API

public interface GitAPI { //请求url:baseURL/users/{user} 下载、返回的响应体为User @Headers("Cache-Control: max-age=64") //设置单个请求的缓存时间 @GET("users/{user}") Call<User> userInfo(@Path("user") String user); //上传图片 @Multipart @POST("uploadaddr") // 根据实际填入 Observable<String> uploadUserFile(@Part("fileName") RequestBody description, @Part("file\"; filename=\"image.png\"")RequestBody img); }

3、创建OkHttpClient、Retrofit对象,执行异步调用

File cacheDirectory = new File(getApplicationContext().getCacheDir().getAbsolutePath(), "Cache"); Cache cache = new Cache(cacheDirectory, 10 * 1024 * 1024)); // 创建缓存类 private Interceptor cacheInterceptor() { return new Interceptor() { //okHttp的Interceptors 可对所有请求进行拦截 @Override public Response intercept(Chain chain) throws IOException { String username = "UserName"; String password = "Password"; String credentials = username + ":" + password; String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); Request request = chain.request(); if (!AppUtil.isNetworkReachable(sContext)) { // 网络不可达,强制使用缓存 request = request.newBuilder() .cacheControl(CacheControl.FORCE_CACHE) //设置缓存控制为"强制缓存" .build(); } //添加请求验证信息头部 Request.Builder requestBuilder = request.newBuilder() //Basic Authentication,也可用于token验证,OAuth验证 .header("Authorization", basic) .header("Accept", "application/json") .method(request.method(), request.body()); Request request0 = requestBuilder.build(); Response response = chain.proceed(request0); if (AppUtil.isNetworkReachable(sContext)) { String cacheControl = request0.cacheControl().toString(); //获取Request缓存设置 if (TextUtils.isEmpty(cacheControl)) { cacheControl = "public, max-age=60"; // 拦截request,添加缓存设置 } return response.newBuilder() .header("Cache-Control", cacheControl) //根据@Headers里的配置,对Response缓存进行设置 .removeHeader("Pragma") .build(); } else { int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale return response.newBuilder() .header("Cache-Control", "public, only-if-cached, max-stale="+maxStale) .removeHeader("Pragma") .build(); } } }; } OkHttpClient client = new OkHttpClient(); //1、初始化OkHttpClient HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); client = new OkHttpClient.Builder() .addInterceptor(cacheInterceptor()) //通过Header和Interceptor配置实现缓存策略, okHttp的拦截器Interceptors可对所有请求进行再处理 .retryOnConnectionFailure(true) .connectTimeout(15, TimeUnit.SECONDS) .cache(cache) // 设置缓存,okhttp默认是没有缓存,且没有缓存目录的 .cookieJar(new CookieJar() { //Cookies由CookieJar统一管理,对CookieJar进行设置就可以达到Cookies缓存 private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { cookieStore.put(url.host(), cookies); } @Override public List<Cookie> loadForRequest(HttpUrl url) { List<Cookie> cookies = cookieStore.get(url.host()); return cookies != null ? cookies : new ArrayList<Cookie>(); } }).build(); Retrofit retrofit = new Retrofit.Builder() //2、创建Retrofit .client(client) //设置OKHttpClient .baseUrl("https://api.github.com/") //设置baseUrl,注意,baseUrl必须后缀"/",Retrofit在创建时候传入了BaseUrl,基本上所有请求都基于该BaseUrl了。 //但是总有些API不是以该BaseUrl开头的(可能不是restful API的),Retrofit提供了注解@Url,可直接对Url进行访问 .addConverterFactory(GsonConverterFactory.create()) //添加Gson转换器 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava2.0 .build(); GitAPI gitAPI = retrofit.create(GitAPI.class); //3、获取GitHub的API //Call方式调用 Call<user> call = gitAPI.userInfo("yourname"); //4、异步调用,最终的请求url:https://api.github.com/users/yourname call.enqueue(new Callback<User>() { @Override public void onResponse(Call<user> call, Response<User> response) { User body = response.body(); Log.d("onResponse", "body = "+body.toString()); } @Override public void onFailure(Call<user> call, Throwable t) { } }); //Observable方式调用(调用RxJava Observable类) String des = "upload a image!"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), des); File file = new File(imgpath); // 图像文件 RequestBody imgbody = RequestBody.create(MediaType.parse("multipart/form-data"),file); Observable<String> observable = gitAPI.uploadUserFile(description, imgbody); observable.subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); .subscribe(new Subscriber<String>() { @Override public void onCompleted() {} @Override public void onError(Throwable e) {} @Override public void onNext(String s) {} }); public class User { private String login; private String id; private String avatar_url; ... private String created_at; private String updated_at; }

//Retrofit加入缓存策略,设置缓存就需要用到OkHttp的interceptors,缓存的设置需要靠请求和响应头 OkHttp3中Cache类是用来定义缓存的,几种缓存策略: noCache :不使用缓存,全部走网络 noStore : 不使用缓存,也不存储缓存 onlyIfCached : 只使用缓存 maxAge :设置最大失效时间,失效则不使用 maxStale :设置最大失效时间,失效则不使用 minFresh :设置最小有效时间,失效则不使用 FORCE_NETWORK : 强制走网络 FORCE_CACHE :强制走缓存

Retrofit注解:Retrofit使用注解来声明API的请求方式、请求参数等 retrofit注解: 方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。 标记注解,包含@FormUrlEncoded、@Multipart、@Streaming。 参数注解,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。 其他注解,@Path、@Header,@Headers、@Url

1、@GET GET网络请求方式 2、@POST POST网络请求方式 3、@Headers() 头信息参数 4、@Path() 路径参数,替换url地址中 { } 所括的部分 5、@Query() 查询参数,将在url地址中追加类似“page=1”的字符串,形成提交给服务端的请求参数 6、@QueryMap 查询参数集合,将在url地址中追加类似 “type=text&username=abc&password=123”的字符串 7、@FormUrlEncoded 对表单域中填写的内容进行编码处理,避免乱码 8、@Field() 指定form表单域中每个空间的额name以及相应的数值 9、@FieldMap 表单域集合 10、@Multipart Post提交分块请求,如果上传文件,必须指定Multipart 11、@Body Post提交分块请求

@HTTP:可以替代其他方法的任意一种 @HTTP(method = "get", path = "users/{user}", hasBody = false) method 表示请的方法,不区分大小写, path表示路径, hasBody表示是否有请求体 Call<ResponseBody> getUser(@Path("user") String user); @Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景。 @GET Call<ResponseBody> getUser(@Url String url); @Streaming:用于下载大文件 @Streaming @GET Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl); // ResponseBody 转换成输入流转存 ResponseBody body = response.body(); long fileSize = body.contentLength(); InputStream inputStream = body.byteStream(); @Path:URL占位符,用于替换和动态更新,相应的参数必须使用相同的字符串被@Path进行注释 @GET("group/{id}/users") //最终的url:http://baseurl/group/groupId/users Call<List<User>> groupList(@Path("id") int groupId); //等同于: @GET Call<List<User>> groupListUrl(@Url String url); // url:http://baseurl/group/groupId/users @Query,@QueryMap:查询参数,用于GET查询,需要注意的是@QueryMap可以约定是否需要encode @GET("group/users") //最终的url:http://baseurl/group/users?id=groupId Call<List<User>> groupList(@Query("id") int groupId); Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options); @Body: 用于POST请求体,将实例对象根据转换方式转换为对应的json字符串参数,这个转化方式是GsonConverterFactory定义的。 @POST("add") Call<List<User>> addUser(@Body User user); @Field@FieldMap: Post方式传递简单的键值对,需要添加@FormUrlEncoded表示表单提交Content-Type:application/x-www-form-urlencoded @FormUrlEncoded @POST("user/edit") Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last); @Part@PartMap:用于POST文件上传,其中@Part MultipartBody.Part代表文件,@Part("description") RequestBody代表参数 需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data @Multipart @POST("upload") Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file); // use the FileUtils to get the actual file by fileUri File file = FileUtils.getFile(this, fileUri); RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // 以文件产生RequestBody对象 MultipartBody.Part body = MultipartBody.Part.createFormData("picture", file.getName(), requestFile); // 从RequestBody对象生成MultipartBody.Part对象 String descriptionString = "hello, this is description speaking"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); // 参数信息 传入body、description变量至upload()方法,形如: ×××.upload(description ,body) @Header:header处理,不能被互相覆盖,用于修饰参数, @GET("user") Call<User> getUser(@Header("Authorization") String authorization) //动态设置Header值 @Headers("Authorization: authorization") //静态设置Header值,authorization就是上面方法里传进来变量的值 @GET("widget/list") Call<User> getUser() @Headers 用于修饰方法,用于设置多个Header值: @Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) @GET("users/{username}") Call<User> getUser(@Path("username") String username);
转载请注明原文地址: https://www.6miu.com/read-23582.html

最新回复(0)