Retrofit 同样是一款由 Square 公司开发的网络库,更侧重于对上层接口的封装
基本用法
通常,服务器提供的接口是按功能归类的,比如新增用户、修改用户数据、查询用户数据等可以归为一类,上架图书,查询在架图书等又可以归为一类。这样的归类能让代码结构变得更加合理,提供可阅读性和可维护性
Retrofit 的用法就是基于以上几点设计的,我们可以对服务器接口进行归类,将功能同属一类的服务器接口定义到同一个接口文件中,从而让代码结构变得更加合理
最后,我们无需关心网络通信的细节,只需在接口文件中声明一系列方法和返回值,然后通过注解的方式指定该方法对应哪个服务器接口,以及需要提供哪些参数。当我们在程序调用该方法时,Retrofit 会自动向对应的服务器接口发起请求,并将响应数据解析成返回值声明的类型
要想使用 Retrofit,我们需要在项目中添加必要的依赖库。编辑 app/build.gradle 文件,在 dependencies 闭包中添加如下内容:
dependencies { ... implementation 'com.squareup.retrofit2:retrofit:2.6.1' implementation 'com.squareup.retrofit2:converter:2.6.1' }
上述第二条依赖是 Retrofit 的转换库,借助 GSON 来解析 JSON 数据。由于 Retrofit 会借助 GSON 将 JSON 数据转换对象,因此这里需要新增一个 App 类,并加入 id、name 和 version 三个字段
class App (val id: String, val name: String, val version: String)
接下来,我们可以根据服务器接口的功能进行归类,创建不同种类的接口文件,并在其中定义对应具体服务器接口的方法
interface AppService { // 发起一条 Get 请求,传入参数是请求地址的相对路径 // 返回值是 Retrofit 内置的 Call 类型,通过泛型来指定服务器响应的数据应该转换为什么对象 @GET("get_data.json") fun getAppData(): Call}
编写一个按钮点击事件,处理具体的网络请求逻辑
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { val retrofit = Retrofit.Builder() .baseUrl("http://127.0.0.1") // 指定所有 Retrofit 请求的根路径 .addConverterFactory(GsonConverterFactory.create()) // 指定 Retrofit 在解析数据时使用的转换库 .build() // 构建 Retrofit 对象 val appService = retrofit.create(AppService::class.java) // 调用 AppService 的 getAppData() 方法,返回 Call// 再调用 enqueue() 方法,Retrofit 会根据注解中配置的服务器接口地址进行网络请求 // 当发起请求时,Retrofit 会自动在内部开启子线程,服务器响应的数据会回调到 Callback 实现里面 appService.getAppData().enqueue(object : Callback
{ override fun onResponse(call: Call
, response: Response
) { val list = response.body() if (list != null) { for (app in list) { Log.d("MainActivity", "id is ${app.id}") Log.d("MainActivity", "name is ${app.name}") Log.d("MainActivity", "version is ${app.version}") } } } override fun onFailure(call: Call
, t: Throwable) { t.printStackTrace() } }) } } }
处理复杂的接口地址类型
服务器不可能总是提供静态类型的接口,很多场景下,接口地址中的部分内容是会动态变化的,比如如下的接口地址:GET http://example.com/
interface AppService { @GET("{page}/get_data.json") fun getData(@Path("page") page: Int): Call}
针对这种接口:GET http://example.com/get_data.json?u=
interface AppService { @GET("get_data.json") fun getData(@Query("u") user: String, @Query("t") token: String): Call }
除了 GET 请求,常用的还有 POST 请求,如果我们需要向服务器提交数据该怎么写呢?
POST http://example.com/data/create {"id": 1, "content": "The description for this data"}
使用 POST 请求来提交数据,需要将数据放到 HTTP 请求的 body 部分,这个功能在 Retrofit 中可以借助 @Body 注解来完成
interface AppService { @POST("/data/create") fun createData(@Body data: Data): Call}
有些服务器接口还会要求我们在 HTTP 请求的 header 中指定参数
interface AppService { @Headers("User-Agent: okhttp", "Cache-Control: max-age=0") @GET("get_data.json") fun getData(): Call }
以及动态指定 header 的值
interface AppService { @GET("get_data.json") fun getData(@Header("User-Agent") userAgent: String, @Header("Cache-Control") cacheControl: String): Call }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)