中文官网: Retrofit
根据官网,新建一个工程学习,在 MainActivity.kt
中使用,我们选用的测试接口为 https://api.github.com/users/{user}/repos
。
别忘了在 AndroidManifest.xml 中添加网络请求权限 <uses-permission android:name="android.permission.INTERNET" />
1. 首先定义接收数据的类
data class DataItem(
val archive_url: String,
val archived: Boolean,
val assignees_url: String,
val blobs_url: String,
val branches_url: String,
val clone_url: String,
val collaborators_url: String,
val comments_url: String,
val commits_url: String,
val compare_url: String,
val contents_url: String,
val contributors_url: String,
val created_at: String,
val default_branch: String,
val deployments_url: String,
val description: String,
val disabled: Boolean,
val downloads_url: String,
val events_url: String,
val fork: Boolean,
val forks: Int,
val forks_count: Int,
val forks_url: String,
val full_name: String,
val git_commits_url: String,
val git_refs_url: String,
val git_tags_url: String,
val git_url: String,
val has_downloads: Boolean,
val has_issues: Boolean,
val has_pages: Boolean,
val has_projects: Boolean,
val has_wiki: Boolean,
val homepage: String,
val hooks_url: String,
val html_url: String,
val id: Int,
val issue_comment_url: String,
val issue_events_url: String,
val issues_url: String,
val keys_url: String,
val labels_url: String,
val language: String,
val languages_url: String,
val license: License,
val merges_url: String,
val milestones_url: String,
val mirror_url: Any,
val name: String,
val node_id: String,
val notifications_url: String,
val open_issues: Int,
val open_issues_count: Int,
val owner: Owner,
val `private`: Boolean,
val pulls_url: String,
val pushed_at: String,
val releases_url: String,
val size: Int,
val ssh_url: String,
val stargazers_count: Int,
val stargazers_url: String,
val statuses_url: String,
val subscribers_url: String,
val subscription_url: String,
val svn_url: String,
val tags_url: String,
val teams_url: String,
val trees_url: String,
val updated_at: String,
val url: String,
val watchers: Int,
val watchers_count: Int
)
data class License(
val key: String,
val name: String,
val node_id: String,
val spdx_id: String,
val url: String
)
data class Owner(
val avatar_url: String,
val events_url: String,
val followers_url: String,
val following_url: String,
val gists_url: String,
val gravatar_id: String,
val html_url: String,
val id: Int,
val login: String,
val node_id: String,
val organizations_url: String,
val received_events_url: String,
val repos_url: String,
val site_admin: Boolean,
val starred_url: String,
val subscriptions_url: String,
val type: String,
val url: String
)
这个文件并不是我一个一个写的,我是根据 json
自动生成的,在 android studio
中自动生成的方法为:
- 装对应的插件,打开
Preferences
对话框下的Plugins
,然后搜索JSON To Kotlin Class
; -
在需要生成的地方,点击鼠标右键:
右键后的图
然后得到:
Generate
点击以后就得到下面的图,粘贴到对应的地方即可:
最终对话框
也可以看到对应的快捷键,使用快捷键就能快速定位到了。
2. 导入 Retrofit 库
在 app
下的 build.gradle
中 dependencies
下添加:
dependencies {
...
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
...
}
3. 定义 baseUrl
然后定义好基础 url
。所谓基础 url
,是指你的请求地址中公共的 url
部分,比如你的请求都是 http://www.baidu.com/user
, http://www.baidu.com/other/search
和 http://www.baidu.com/id
等等,那么就是 http://www.baidu.com/
了。
private val API_URL = "https://api.github.com"
4. 声明请求响应接口
绑定返回的数据和请求接口:
interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") user: String?): Call<List<DataItem?>?>?
}
其中 @GET
就是代表使用 GET
请求,后面就是所对应的请求路径;如果路径中有变量的,就是像上面 {user}
那样; @Path
专门就是用于像 {user}
这样的参数。而函数是使用 Call
包括返回的数据,比如这里就是一个数组,数组的每一项是 DataItem
,这个就是上面我定义的类型。
5. 实例化 Retrofit 对象
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
可以看到中文官网上是这样的:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
不能这样,如果只是这样的话,那么会出现像 Unable to create converter for java.util.List<com.example.retrofit2activity.MainActivity$DataItem>
这样的错误。
而 GsonConverterFactory.create()
是固定的,这个依赖于上面的 implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
。
6. 创建对应的请求实例
val service: GitHubService = retrofit.create(GitHubService::class.java)
6. 使用
val repos = service.listRepos("wutiange")
repos?.enqueue(object : Callback<List<DataItem?>?> {
override fun onResponse(call: Call<List<DataItem?>?>, response: Response<List<DataItem?>?>) {
println("吴敬悦")
response.body()?.forEach {
println(it)
}
}
override fun onFailure(call: Call<List<DataItem?>?>, t: Throwable) {
println("失败了${t.message}")
}
})
这里之所以使用 enqueue
,是因为我现在在主线程,主线程不能处理异步请求,如果你本身就是在其他线程(协程)里面,那么就可以 execute
了。如果在此时出现了 socket failed: EPERM (Operation not permitted)
这样的错误,那么只需要将原来的 APP
卸载掉,重新安装即可。
网友评论