Fellow Travellers

Retrofit简单封装

汪洋
字数统计: 1.3k阅读时长: 6 min
2018/05/11 Share

#Retrofit简单封装

1 简介

一个Restful的HTTP网络请求框架(基于OKHttp)

1.1 功能

  • 基于OKHttp & 遵循Restful API设计风格
  • 通过注解配置网络请求参数
  • 支持同步 & 异步网络请求
  • 支持多种数据的解析 & 序列化格式(Gson、JSON、XML、Protobuf)
  • 提供 RxJava支持

1.2 优点

  • 简洁易用:通过注解配置网络请求参数、采用大量设计模式简化使用
  • 可拓展性好:功能模块高度封装、解耦彻底,如自定义Converters等
  • 功能强大: 支持同步异步,支持各种数据解析,支持RxJava

1.3 本质

Retrofit是一个Restful的HTTP网络请求框架的封装,它的网络请求由OKHttp完成。

2 基本使用方式

2.1 引用

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

2.2 创建实例

1
2
3
4
5
Retrofit retrofit = new Retrofit.Builder().baseUrl(“http://fy.iciba.com/”)
// 设置网络请求 Url
.addConverterFactory(GsonConverterFactory.create())
//设置使用Gson解析
.build()

2.3 接口定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public  class Translation {
private int status
private content content
private static class content {
private String from
private String to
private String vendor
private String out
private int errNo
}
}
public void show() {
System.out.println(status)
System.out.println(content.from)
}
public interface GetRequest_Interface {
@GET(“ajax.php?a=fy&f=auto&t=auto&w=hello%20world”)
Call<Translation> getCall()
// 注解里传入 网络请求 的部分 URL地址
getCall()是接受网络请求数据的方法
}

2.4 接口调用

1
2
3
4
//创建接口实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class)
//对发送请求 进行封装
Call<Translation> call = request.getCall()

2.5 执行网络请求

1
2
3
4
5
6
7
8
9
10
11
12
Call<Translation> call = request.getCall()
//异步请求
call.enqueue(new CallBack<Translation>) {
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
response.body().show();
}
@Override
public void onFailure(Call<Translation> call, Throwable throwable) {
System.out.println(“连接失败”)
}
}

3 封装目的

  • 多个接口需要多个定义: 利用@Url注解
  • 每个请求结果需要定义对应Model: 利用Call
  • 代码结构混乱: 封装Retrofit

传递需要的参数,调用方法,回调获取数据

4 封装过程

4.1 对象表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface RetrofitRequestBlock {
fun requestBlock(response: Any?, errStr: String?)
}


interface RetrofitDownloadRequestBlock {
fun updateProgress(progress: Int, done: Boolean, filePath: String, errorMessage: String?)
}


interface RetrofitDownloadAndDecompressBlock: RetrofitDownloadRequestBlock {
fun updateDecompressProgress( decompressState: ArchiveUtil.DecompressState, progress: Int, done: Boolean, decompressPath: String, errorMessage: String?)
}

// 用户登录
fun requestLoginValidate(name:String?,pwd:String?,code: String?, block: RetrofitRequestBlock) {
val baseStr = Globe.baseUrl
val restStr = Globe.loginUrl
val method = HttpMethod.get
val params = mapOf("type" to "user","un" to name,"pwd" to pwd,"devicecode" to code,"action" to "login")
request(method,baseStr,restStr,params,block)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
NetWorkManager.requestLoginValidate(encodeUserName,encodeUserPwd,DeviceValitation.deviceCode,object : NetWorkManager.RetrofitRequestBlock {
override fun requestBlock(response: Any?, errStr: String?) {
if (errStr != null) {
Toast.makeText(this@LoginActivity,"login failure: $errStr",Toast.LENGTH_SHORT).show()
} else {
if (response != null) {
val jsonData = response as JSONObject

if (jsonData.has("status") && jsonData["status"] == "false") {
val message = jsonData["loginState"] as String
Toast.makeText(this@LoginActivity,"login failure: $message",Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@LoginActivity,"login success!!",Toast.LENGTH_SHORT).show()
loginSuccessfully(jsonData)
}
}
}
}
})

4.2 lambda表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private fun MapActivity.getEssentialKeys(layerGUID: String?,block: (List<String>) -> Unit) {
if (layerGUID != null) {
val list = essensialFieldsMap[layerGUID]
if (list != null ) {
block.invoke(list)
return
}
NetWorkManager.requestLayerFields(layerGUID, object : NetWorkManager.RetrofitRequestBlock {
override fun requestBlock(response: Any?, errStr: String?) {
if (errStr == null && response != null) {
val fieldKeystr = ((response as JSONArray)[0] as JSONObject)["layerField"]
val fieldKeys = JsonUtil.jsonToList(fieldKeystr.toString(),Array<String>::class.java)
essensialFieldsMap[layerGUID] = fieldKeys
block.invoke(fieldKeys)
}
}
})
}
}
1
2
3
4
5
6
7
8
9
10
11
getEssentialKeys(k,{ list ->
if (list.isNotEmpty()) {
val essentialAtt = sortedAttributes.filter { list.contains(it.first) }
content.text_sub.text = Html.fromHtml(dealWithAttributes(essentialAtt))
content.more.visibility = View.VISIBLE
} else {
content.more.visibility = View.GONE
content.text_sub.visibility = View.GONE
content.text.visibility = View.VISIBLE
}
})

4.3 接口封装与定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface RetrofitHttpService {
@GET
fun getRequest(@Url url: String, @QueryMap params: Map<String, String?>?): Call<ResponseBody>

@Headers("Content-Type: application/json","Accept: application/json")
@POST
fun postRequest(@Url url: String,@Body info:RequestBody): Call<ResponseBody>

@GET
fun Obget(@Url url: String, @QueryMap params: Map<String, String>, @HeaderMap headers: Map<String, String>?): Call<String>

@FormUrlEncoded
@POST
fun Obpost(@Url url: String, @FieldMap params: Map<String, String>, @HeaderMap headers: Map<String, String>?): Call<String>

@FormUrlEncoded
@PUT
fun Obput(@Url url: String, @FieldMap params: Map<String, String>, @HeaderMap headers: Map<String, String>?): Call<String>

@Streaming
@GET
fun Obdownload(@HeaderMap headers: Map<String, String>, @Url url: String, @QueryMap params: Map<String, String>?): Call<ResponseBody>

@Streaming
@GET
fun download(@HeaderMap headers: Map<String, String>, @Url url: String, @QueryMap params: Map<String, String>?): Call<ResponseBody>

@Streaming
@GET
fun download(@Url url: String, @QueryMap params: Map<String, String>): Call<ResponseBody>
}

4.4 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private fun request(method:HttpMethod,baseUrlStr: String,restUrlStr: String,params: Map<String,String?>?,block: RetrofitRequestBlock) {

val retrofit = Retrofit.Builder().baseUrl(baseUrlStr).build()
val service = retrofit.create(RetrofitHttpService::class.java)
var call: Call<ResponseBody>?
when (method) {
HttpMethod.get ->
call = service.getRequest(restUrlStr,params)
HttpMethod.post -> {
val requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),JsonUtil.toJson(params!!))
call = service.postRequest(restUrlStr,requestBody)
}
}

call.enqueue(object :Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
// successCallBack.Success(response!!.body())
if (response!!.body() == null) {
block.requestBlock(null,"服务器异常!!")
} else {
val jsonData = JSONObject(response!!.body()!!.string())
if (jsonData["status"] == "true") {
block.requestBlock(jsonData["data"], null)
} else {
block.requestBlock(null, jsonData["message"] as String)
}
}
}

override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
block.requestBlock(null,t?.localizedMessage)
}
})
}
CATALOG
  1. 1. 1 简介
    1. 1.1. 1.1 功能
    2. 1.2. 1.2 优点
    3. 1.3. 1.3 本质
  2. 2. 2 基本使用方式
    1. 2.1. 2.1 引用
    2. 2.2. 2.2 创建实例
    3. 2.3. 2.3 接口定义
    4. 2.4. 2.4 接口调用
    5. 2.5. 2.5 执行网络请求
  3. 3. 3 封装目的
  4. 4. 4 封装过程
    1. 4.1. 4.1 对象表达式
    2. 4.2. 4.2 lambda表达式
    3. 4.3. 4.3 接口封装与定义
    4. 4.4. 4.4 使用