RxJava2 OkHttp Rerofit简易封装

今天抽空将Java版的RxJava2、 OkHttp、 Rerofit三者结合简易封装的示例,
再用Kotlin写了一遍,最大区别由于Kotlin代码真的少太多有没有?


导入第三方库

1
2
3
4
5
6
7
8
9
10
//json解析
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
//将数据以rxjava2方式返回
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
//rxandroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
//rxjava2
implementation "io.reactivex.rxjava2:rxjava:2.1.1"

OkHttp封装

  • 全局就OkHttpWrapper类下的一个静态OkHttpClient
  • init中初始化它,设置超时时间等
  • 还可以添加拦截器(使用统一header、处理461 401等异常、性能统计、打印请求响应数据、或其他特定功能拦截器)
1
2
3
4
5
6
7
8
9
10
11
12
class OkHttpWrapper {
companion object {
val okhttp : OkHttpClient
init {
okhttp = OkHttpClient().newBuilder()
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build()
}
}
}

Retrofit封装

  • 支持多BaseUrl随意使用的Retrofit封装
  • 使用了GsonConverterFactory RxJava2CallAdapterFactory 对返回数据作处理
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

class RetrofitManager() {
private val retrofitManagers = HashMap<String,RetrofitManager>()
private lateinit var mRetrofit: Retrofit
constructor(baseUrl: String) : this() {
var retrofitManager = retrofitManagers.get(baseUrl)
if (retrofitManager == null) {
retrofitManager = RetrofitManager()
retrofitManager.mRetrofit = Retrofit.Builder()
.client(OkHttpWrapper.okhttp)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
retrofitManagers.put(baseUrl, retrofitManager)
}
mRetrofit = retrofitManager.mRetrofit
}
/**
* @param service 服务接口
* @return T
*/
fun <T> createService(service: Class<T>): T {
return mRetrofit.create(service)
}
}

RxJava2封装

replay 操作封装

  • 主要封装RxJava2 中的 replay 操作
  • 一般来说,服务端都会返回是否成功,以及错误msg等信息。这里的封装就是针对这种情况做统一数据处理,及数据类型转换等工作
  • 我这里仅用https://interface.meiriyiwen.com/article/today?dev=1的数据简单做了一个处理
1
2
3
4
5
6
7
8
9
10
11
12
class ArticleFuncation<T> : Function<Observable<Article<T>>, Observable<T>> {
override fun apply(t: Observable<Article<T>>): Observable<T> {
return t.subscribeOn(AndroidSchedulers.mainThread())
.map(Function<Article<T>, T> { t ->
if (t != null) {
return@Function t.data
}
return@Function null!!
})
.filter { t -> t != null }
}
}

Observer 数据回调封装

  • 重写BaseObserver类之后就只需要实现onResponse(isSuccess: Boolean, t: T?)方法,包含成功失败,及返回所需数据。
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
abstract class BaseObserver<T> : Observer<T> {
private var mDisposable: Disposable? = null
abstract fun onResponse(isSuccess: Boolean, t: T?)
override fun onSubscribe(@NonNull d: Disposable) {
mDisposable = d
}
override fun onNext(@NonNull t: T) {
onResponse(true, t)
}
override fun onError(@NonNull e: Throwable) {
onResponse(false, null)
disposed()
}
private fun disposed() {
if (mDisposable != null && !mDisposable!!.isDisposed) {
mDisposable!!.dispose()
}
}
/**
* 如需该回调,可手动重写该方法
*/
override fun onComplete() {
disposed()
}
}

重点,正式使用

  • 定义Retrofit的Service接口
  • 注意:这里返回的Article就是服务端返回的数据,其实我们就只要Data数据操作就好。
1
2
3
4
interface ArticleService{
@GET("/article/today")
fun getArticle(@Query("dev") dev: String): Observable<Article<Data>>
}
  • Activity 网络获取及数据显示
  • 注意:上述的数据处理在这(replay(ArticleFuncation()))
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
class MainActivity : AppCompatActivity() {

private val baseUrl = "https://interface.meiriyiwen.com"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

class myObserver : BaseObserver<Data>() {
override fun onResponse(isSuccess: Boolean, t: Data?) {
if (isSuccess) {
var content = t?.content
if (content != null)
txt.text = Html.fromHtml(content)
else
txt.text = "获取数据为空"
}
else
txt.text = "获取数据失败"
}
}

RetrofitManager(baseUrl)
.createService(ArticleService::class.java)
.getArticle("1")
.subscribeOn(Schedulers.io())
.replay(ArticleFuncation<Data>())
.subscribe( myObserver())
}
}

本篇完