IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 最好用的网络库 Retrofit -> 正文阅读

[移动开发]Android 最好用的网络库 Retrofit


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<List<App>>
}

? 编写一个按钮点击事件,处理具体的网络请求逻辑

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<List<App>>
            // 再调用 enqueue() 方法,Retrofit 会根据注解中配置的服务器接口地址进行网络请求
            // 当发起请求时,Retrofit 会自动在内部开启子线程,服务器响应的数据会回调到 Callback 实现里面
            appService.getAppData().enqueue(object : Callback<List<App>> {
                override fun onResponse(call: Call<List<App>>, response: Response<List<App>>) {
                    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<List<App>>, t: Throwable) {
                    t.printStackTrace()
                }
            })
        }
    }
}

处理复杂的接口地址类型

服务器不可能总是提供静态类型的接口,很多场景下,接口地址中的部分内容是会动态变化的,比如如下的接口地址:GET http://example.com/<page>/get_data.json,这种接口地址对应到 Retrofit 中该怎么写呢?

interface AppService {

    @GET("{page}/get_data.json")
    fun getData(@Path("page") page: Int): Call<Date>
}

<page> 部分代表页数,使用一个 {page} 的占位符,又在 getData() 方法添加一个 page 参数,使用 @Path("page") 注解声明这个参数

针对这种接口:GET http://example.com/get_data.json?u=<user>$t=<token>,Retrofit 专门提供了一种语法支持

interface AppService {

    @GET("get_data.json")
    fun getData(@Query("u") user: String, @Query("t") token: String): Call<Data>
}

除了 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<ResponseBody>
}

有些服务器接口还会要求我们在 HTTP 请求的 header 中指定参数

interface AppService {

    @Headers("User-Agent: okhttp", "Cache-Control: max-age=0")
    @GET("get_data.json")
    fun getData(): Call<Data>
}

以及动态指定 header 的值

interface AppService {

    @GET("get_data.json")
    fun getData(@Header("User-Agent") userAgent: String,
                    @Header("Cache-Control") cacheControl: String): Call<Data>
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:13:34  更:2022-01-03 16:14:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:34:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码