APP下载
报价宝  ›  科技  › 

入门Retrofit 看这一篇就够了

报价宝 来源:baojiabao.com 发布时间:2019-07-01 20:02:00 11月05日更新
报价宝综合消息入门Retrofit 看这一篇就够了

本文主要对Android中经常使用的网络请求框架Retrofit做简单介绍,抛砖引玉,希望可以帮大家快速入门Retrofit的使用。

本文目录如下:

Retrofit介绍

Retrofit是Square公司开发的一款针对Android和java的网络请求框架,遵循Restful设计风格,底层基于OkHttp。

Retrofit具有以下主要功能:

支援同步/异步网络请求支援多种资料的解析&序列化格式(Gson、json、XML等等)通过注解配置网络请求引数提供对Rxjava的支援高度解耦,使用方便相比去其他网络请求框架,其具有效能特别棒、使用特别方便的特性,所以在任何网络请求场景下,我们都应该有限考虑Retrofit,本文就Retrofit的入门使用和简单特性做简单介绍,抛砖引玉,希望大家可以爱上Retrofit。

基础使用步骤

我们首先通过一个简单的案例带大家走一遍使用Retrofit的完整流程,然后再深入介绍Retrofit的一些特性。

我们要做的就是在Android中使用Retrofit发起网络请求,将下图(图片地址:http://picture-pool.oss-cn-beijing.aliyuncs.com/2019-06-29-121904.png)下载并展示出来,下面我来一步一步介绍如何去做。

新增依赖

在Gradle档案中新增如下依赖:

implementation 'com.squareup.retrofit2:retrofit:2.6.0'

宣告网络许可权

在Android的manifest配置档案中宣告网络请求许可权:

建立用于配置网络请求的界面

Retrofit将 Http请求抽象成 Java界面,采用注解来描述配置网络请求引数,何为配置网络请求引数?说白了就是设定网络请求的地址是什么、使用什么请求方法、传递的引数是什么、返回值型别是什么等等一系列配置资讯,通过界面描述清楚这些具体的网络配置资讯,Retrofit才能根据你的配置发起最终的网络请求。所以我们首先应该宣告一个用于配置网络请求的Java界面:

/**

* @author dmrfcoder

* @date 2019-06-29

*/

public interface GetRequestInterface {

/**

*

*

* 通过get()方法获取图片的请求界面

* GET注解中的引数值"2019-06-29-121904.png"和Retrofit的base url拼接在一起就是本次请求的最终地址

*

* @return

*

*/

@GET("2019-06-29-121904.png")

Call getPictureCall();

}

建立Retrofit例项并发起网络请求

这里直接给出程式码,重点都在注释中:

public void retrofitGet() {

/*

建立Retrofit物件,这里设定了baseUrl,注意我们在宣告网络配置界面GetRequestInterface的时候在GET注解中也声明了一个Url,

我们将会这里的baseUrl和GET注解中设定的Url拼接之后就可以形成最终网络请求实际访问的url

*/

Retrofit retrofit = new Retrofit.Builder().baseUrl("http://picture-pool.oss-cn-beijing.aliyuncs.com/").build();

//建立网络请求配置的界面例项

GetRequestInterface getRequestInterface = retrofit.create(GetRequestInterface.class);

//呼叫我们宣告的getPictureCall()方法建立Call物件

Call requestBodyCall = getRequestInterface.getPictureCall();

//使用requestBodyCall发起异步网络请求

requestBodyCall.enqueue(new Callback() {

@Override

public void onResponse(Call call, Response response) {

//将网络请求返回的资料解析为图片并展示到界面

ResponseBody body = response.body();

InputStream inputStream = body.byteStream();

Drawable drawable = Drawable.createFromStream(inputStream, "pic.png");

imageView.setBackground(drawable);

Log.e(TAG, "网络请求成功");

}

@Override

public void onFailure(Call call, Throwable t) {

Log.e(TAG, "网络请求失败,失败原因:" + t.getMessage());

}

});

}

如果使用过OkHttp的读者可能很熟悉最后两步建立Call物件、发起异步网络请求的操作,几乎和OkHttp一模一样,这是因为Retrofit就是基于OkHttp的啊~~

最终效果如下:

细心的读者可能发现了一个问题,在上面的程式码中我是直接在CallBack界面的onResponse()回拨方法中更新的ImageView,即在onResponse()中更新UI的,在OkHttp中这个onResponse()方法是在子执行绪中被呼叫的,而在Retrofit中,onResponse()和onFailure()这两个回拨方法都是在主执行绪进行呼叫的,所以可以在其中直接更新UI,这也是Retrofit和OkHttp的一点不同之处。

Retrofit使用详解

通过上面的例子带大家走了一遍Retrofit的整体流程,让大家对Retrofit有了一个整体的感知,接下来我们来逐步深入了解一下Retrofit的具体使用。

请求方法

每一个方法都必须有一个HTTP注解,用来提供网络请求的请求方法以及相对URL。在Retrofit中可以使用五种请求方法:GET,POST,PUT,DELETE,HEAD,而相对URL直接在对应注解中填写即可,比如:

@GET("users/list")//表示以GET请求方法发起网络请求,子URL为:users/list

你可以在URL中直接指定查询的引数:

@GET("users/list?sort=desc")

URL操作

网络请求的URL可以通过结合占位符和方法中的引数的方式来进行动态更新,所谓的占位符指的是URL中由{}包裹的String型别字串,而引数必须使用@Path注解进行修饰,而且也只能是String,这样,@Path修饰的变数会动态对应到URL中,比如:

@GET("group/{id}/users")

Call> groupList(@Path("id") int groupId);

如上面的程式码所示,当代码执行的时候,groupId会被动态系结到子URL中{id}所占的位置上,达到动态设定URL的作用。

查询引数也可以使用类似的方法进行设定:

@GET("group/{id}/users")

Call> groupList(@Path("id") int groupId, @Query("sort") String sort);

如果查询引数太多,还可以使用Map:

@GET("group/{id}/users")

Call> groupList(@Path("id") int groupId, @QueryMap Map options);

请求体

我们可以通过@Body注解将一个物件以 Post方式传送给服务器:

@POST("users/new")

Call createUser(@Body User user);

标记注解

当我们想传送form-encoded的资料时,可以使用@FormUrlEncode注解,将每个键值对中的键使用@Filed注解来进行说明,而值设定为随后跟随的物件:

@FormUrlEncoded

@POST("user/edit")

Call updateUser(@Field("first_name") String first, @Field("last_name") String last);

当我们想传送Multipart的资料时(适用于档案传送的场景),可以使用@Multipart注解,时使用,将每个键值对中的键使用@Part注解来进行说明,而值设定为随后跟随的物件:

@Multipart

@PUT("user/photo")

Call updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

Header操作

你可以通过使用@Headers注解为请求方法设定静态请求头:

@Headers("Cache-Control: max-age=640000")

@GET("widget/list")

Call> widgetList();

或者像这样:

@Headers({

"Accept: application/vnd.github.v3.full+json",

"User-Agent: Retrofit-Sample-App"

})

@GET("users/{username}")

Call getUser(@Path("username") String username);

注意,请求头中不会进行覆盖,即如果你设定两个相同键的请求头,这两个请求头都会被发送。

请求头可以使用@Header进行动态更新,前提是设定了合法的请求头,如果你设定了型别为null的请求头,那么对应的请求头会被忽略,如果不为null,将最终会发送你设定引数的toString()结果。

@GET("user")

Call getUser(@Header("Authorization") String authorization)

和查询引数的设定方法类似,当请求头的引数过于复杂时,你也可以使用Map:

@GET("user")

Call getUser(@HeaderMap Map headers)

同步请求和异步请求

Call例项可以使用同步和异步两种方式进行执行,每一个例项都仅仅只能被执行一次,但是,你可以通过呼叫clone()方法拷贝一份新的、同样的Call例项,以达到多次请求的目的。

在Android中,Call的回拨界面会在主执行绪中执行,在JVM中,回拨界面会在发起请求的当前执行绪中执行。

转换器(converters)

预设情况下,Retrofit只能反序列化OkHttp中的ResponseBody型别的返回值,通过新增不同型别的转换器可以使Retrofit拥有反序列化其他主流序列的能力,以下是一些常用转换器的列表:

Gson:com.squareup.retrofit2:converter-gsonJackson:com.squareup.retrofit2:converter-jacksonMoshi:com.squareup.retrofit2:converter-moshiProtobuf:com.squareup.retrofit2:converter-protobufWire:com.squareup.retrofit2:converter-wireSimple XML:com.squareup.retrofit2:converter-simplexml下面是一个使用GsonConverterFactory类反序列化GithubService返回结果的例子:

Retrofit retrofit = new Retrofit.Builder()

.baseUrl("https://api.github.com")

.addConverterFactory(GsonConverterFactory.create())

.build();

GitHubService service = retrofit.create(GitHubService.class);

网络请求界面卡(CallAdapter)

Retrofit支援多种网络请求界面卡方式:guava、Java8和rxjava

使用时如使用的是 Android 预设的 CallAdapter,则不需要新增网络请求界面卡的依赖,否则则需要按照需求进行新增 Retrofit 提供的 CallAdapter,对应依赖为:

guava :com.squareup.retrofit2:adapter-guava:x.x.xJava8:com.squareup.retrofit2:adapter-java8:x.x.xrxjava:com.squareup.retrofit2:adapter-rxjava:x.x.x这里使用rxjava来发起之前例子中的网络请求:

首先修改网络请求的界面:

public interface GetRequestInterfaceWithRxJava {

/**

* 通过get()方法获取图片的请求界面

* GET注解中的引数值"2019-06-29-121904.png"和Retrofit的base url拼接在一起就是本次请求的最终地址

*

设定返回值型别为Observable的

* @return

*/

@GET("2019-06-29-121904.png")

Observable getPictureCall();

}

然后使用RxJava发起网络请求:

public void retrofitGetWithRxJava() {

/*

建立Retrofit物件,这里设定了baseUrl,注意我们在宣告网络配置界面GetRequestInterface的时候在GET注解中也声明了一个Url,

我们将会这里的baseUrl和GET注解中设定的Url拼接之后就可以形成最终网络请求实际访问的url

*/

Retrofit retrofit = new Retrofit.Builder().baseUrl("http://picture-pool.oss-cn-beijing.aliyuncs.com/").addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();

//建立网络请求配置的界面例项

GetRequestInterfaceWithRxJava getRequestInterfaceWithRxJava = retrofit.create(GetRequestInterfaceWithRxJava.class);

//呼叫我们宣告的getPictureCall()方法建立Call物件

Observable requestObservable = getRequestInterfaceWithRxJava.getPictureCall();

requestObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {

@Override

public void onSubscribe(Disposable d) {

Log.e(TAG, "onSubscribe");

}

@Override

public void onNext(ResponseBody body) {

//将网络请求返回的资料解析为图片并展示到界面

InputStream inputStream = body.byteStream();

Drawable drawable = Drawable.createFromStream(inputStream, "pic.png");

imageView.setBackground(drawable);

Log.e(TAG, "网络请求成功");

}

@Override

public void onError(Throwable e) {

Log.e(TAG, "onError:" + e.getMessage());

}

@Override

public void onComplete() {

Log.e(TAG, "onComplete");

}

});

}

执行效果和之前的程式码一样:

总结

本文介绍了Retrofit的基本使用和常用API,希望可以帮大家对Retrofit有一个入门的认识,后面我会推出有关Retrofit源代码分析等一系列文章,欢迎大家关注。
文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 数码相机价格 汽车价格 笔记本电脑价格 华为手机价格 红米手机价格