之前小萌新直接上项目,然后立马就用上了Rretrofit和Rxjava来做,没有特别去学习,然后直接就干了。看了看别人的用法。 后面也根据个人请求数据结果进行了封装,总共封装了两两次,基本实现了通用请求,一个请求方法就搞定所有请求,返回不同的对象或者对象列表
MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-初步封装-相关关键类
MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-二次封装-下载上传/类型转换完善
MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-再次封装-利用泛型搞定不同对象解析
以上就是之前做项目关于Retrofit/Rxjava的学习,上去就干了,没有看太多,这样确实不太好!还是该补补知识妮...于是乎,我们从官方案例开始,小萌新是从一个B站的国外的教学视频开始的,那个帅哥老外基本把官方案例全部都实践教学了一遍,同时也是进行了扩展教学!
开始前准备!
https://www.bilibili.com/video/av47872658 - 时间不长,一上午基本就可以看完,加油,么么哒!
官方【看官方比较锻炼记几个,I think】文档还是得有: Retrofit - 里面基本使用方法 GitHub地址: square/retrofit
小萌新是Kotlin工程做的实践工程,基本知识时间长了不用,容易遗忘,而且再不是很熟练的情况下和其他语言来回切换容易混淆,所以需要补补Kotlin 基础语法 | 菜鸟教程
另外测试接口可以在线测试(其他工具也可以,像postman这些) 在线HTTP接口测试工具 - Getman ,比如官方的是github获取用户开源项目列表的请求接口,为了看返回的列表结构,我们可以提前看下返回结构!如下:
准备差不多了,可以开始来搞起了!
看下官方的初步创建和使用:
其中关于@Path,我用的确实少,主要是接口一般都很少中间需要动态参数的,不过有必要了解!
一、下面是关于get/post请求相关参数介绍
**@Path **用来将参数拼接到请求url中
**@Header **用来添加信息到请求头 - 官方还说了Headers that need to be added to every request can be specified using anOkHttp interceptor. 如果需要每个请求都添加,那请求再OkHttp的拦截器里面统一处理.
二、了解以上知识后,我们就可以开始实践之路了
添加依赖哟build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
**Repo.kt **- 根据前面在线测试接口返回数据(取几个字段来创建实体类就好)
package com.hl.rxnettest
class Repo{
var id: Long = -1
public var name: String? = null
var full_name: String? = null
// class owner - not need
var html_url: String? = null
var description: String? = null
}
ToStringConverterFactory.java - 字符串结构类型返回转换器 - 这里java也可以喲
package com.hl.rxnettest;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public class ToStringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter() {
@Override
public String convert(ResponseBody value) throws IOException {
return value.string();
}
};
}
return null;
}
@Override public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter() {
@Override
public RequestBody convert(String value) throws IOException {
return RequestBody.create(MEDIA_TYPE, value);
}
};
}
return null;
}
}
GitHubService.kt - 定义请求服务接口【定义了三种不同类型的返回结果】
package com.hl.rxnettest
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
interface GitHubService {
// 无需添加解析器- 返回原始ResponseBody
@GET("users/{user}/repos")
fun listReposResponseBody(@Path("user") user: String): Call
// 添加ToStringConverterFactory解析器 - 返回字符串结果【本质:ResponseBody value -> value.string()】
@GET("users/{user}/repos")
fun listReposString(@Path("user") user: String): Call
// 添加GsonConverterFactory解析器 - 返回Json解析的对象列表
@GET("users/{user}/repos")
fun listRepos(@Path("user") user: String): Call>
}
MainActivity.kt - 三种不同的请求方式调用
package com.hl.rxnettest
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.ResponseBody
import retrofit2.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Example of a call to a native method
sample_text.text = stringFromJNI()
// Retrofit使用学习
// 创建Retrofit请求对象
var retrofit: Retrofit = Retrofit.Builder()
// 设置数据解析器`
// 无需解析 -> 方式0
// Json解析 -> 方式1
// .addConverterFactory(GsonConverterFactory.create())
// 字符串解析 -> 方式2
// .addConverterFactory(ToStringConverterFactory())
// 设置网络请求地址
.baseUrl("https://api.github.com/")
.build()
// 创建GitHubService请求服务
// person::class 和Person::class都是获取kotlin的KClass -> 先获取到kotlin的KClass然后再获取javaClass
// 说明: https://blog.csdn.net/fly7632785/article/details/79863049
var gitHubService = retrofit.create(GitHubService::class.java)
// UI线程中同步执行错误提示 - Caused by: android.os.NetworkOnMainThreadException
// var repos = gitHubService.listRepos("FanChael")
// var response = repos.execute()
// 方式0: 创建网络请求接口实例 - 返回ResponseBody结果,response.body()?.string()自己进行解析
var reposResponseBody = gitHubService.listReposResponseBody("FanChael")
reposResponseBody.enqueue(object : Callback{ // object的作用是调用内部匿名类
override fun onResponse(call: Call, response: Response){
// Returns true if the code is in [200..300)
if (response.isSuccessful) {
// response.body() -> ResponseBody
Log.e("reposResponseBody-s", response.body()?.string())
} else {
Log.e("reposResponseBody-s-f", "请求错误了!")
}
}
override fun onFailure(call: Call, t: Throwable){
Log.e("reposResponseBody-f", t.message)
}
})
/*
// 方式1: 创建网络请求接口实例 - 返回字符串结果
var reposString = gitHubService.listReposString("FanChael")
reposString.enqueue(object : Callback{ // object的作用是调用内部匿名类
override fun onResponse(call: Call, response: Response){
if (response.isSuccessful) {
// response.body() -> String
Log.e("reposString-onResponse", response.body())
} else {
Log.e("reposString-onResponse", "请求错误了!")
}
}
override fun onFailure(call: Call, t: Throwable){
Log.e("reposString-onFailure", t.message)
}
})*/
/*
// 方式2: 创建网络请求接口实例 - Gson解析后返回对象列表
var repos = gitHubService.listRepos("FanChael")
// 发起请求,UI线程需要异步请求
repos.enqueue(object : Callback>{ // object的作用是调用内部匿名类
override fun onResponse(call: Call>, response: Response>){
if (response.isSuccessful) {
// response.body() -> List
Log.e("repos-onResponse", response.body()?.get(0)?.name)
} else {
Log.e("repos-onResponse", "请求错误了!")
}
}
override fun onFailure(call: Call>, t: Throwable){
Log.e("repos-onFailure", t.message)
}
})*/
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
external fun stringFromJNI(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
}
以上可以分别打开/注释来测试不同的方式(方式1和2请设置对应的转换器,同时设置,最后一次设置有效!)
**二.1 **关于Kotlin类的class获取的方式 retrofit.create(GitHubService::class.java),如下 https://blog.csdn.net/fly7632785/article/details/79863049 :
**二.2 **其中ToStringConverterFactory这个转换器,主要做了如下工作:
其实就是获取了ResponseBody的string()字符串,所以其实我们也可以直接采用方式0,返回ResponseBody的结果,然后获取:
当然我们定义一个转换器,看起来更清晰,也更方便了呀!后面可以看下FastJson转换器的源码,应该就更清晰了呀啦!
差不多今天就是这样搞了搞,算是入门了吧,小皮球....那个视频里面讲了一些Okhttp日志的拦截,然后大部分都是讲了请求参数的处理(什么header, 什么认证呀,什么token呀,还要就是添加拦截器等),下一篇,我们争取过一遍那些案例,实践实践!
到这里,本来想着结束,一想,小萌新觉得有必要贴下结束:
Retrofit其实我们可以理解为OkHttp的加强版,它也是一个网络加载框架。底层是使用OKHttp封装的。准确来说,网络请求的工作本质上是OkHttp完成,
而 Retrofit 仅负责网络请求接口的封装。它的一个特点是包含了特别多注解,方便简化你的代码量。并且还支持很多的开源库(著名例子:Retrofit + RxJava)。
都是square公司的。还有https://github.com/AndroidKnife/RxBus,基于rxjava搞的.. Rx家族目前来看还不错...
OkHttp是核心
另外就是API在线文档:
Retrofit 2.3.0 APIsquare.github.io
不会了,就慢慢来,但是自己不要老是堕落,玩耍,浪费时间,说的就是我!哼!
打算自己学习造个轮子...
https://github.com/FanChael/RxNet