一个基于 Kotlin + Jetpack + Coroutines + Retrofit 封装的网络请求框架
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
dependencies {
implementation 'com.github.leavesCZY:ReactiveHttp:1.1.3'
}
更多介绍请看这里:wiki
一个基于 Kotlin + Jetpack + Coroutines + Retrofit 封装的网络请求框架
一个基于 Kotlin + Jetpack + Coroutines + Retrofit 封装的网络请求框架
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
dependencies {
implementation 'com.github.leavesCZY:ReactiveHttp:1.1.3'
}
更多介绍请看这里:wiki
在阅读RetrofitManagement
里的applySchedulers()
,读这段代码可以发现,这个方法的返回类型是 ObservableTransformer
,但最后调用的方法flatMap
的返回类型却是 Observable
类型, 而 Observable
并不继承或者实现 ObservableTransformer
,为什么会这样,而且这样编辑器还不会报错,不是flatMap
方法的返回类型应该和这个方法返回类型的本身保持一致吗?
applySchedulers
代码:
<T> ObservableTransformer<BaseResponseBody<T>, T> applySchedulers() {
return observable -> observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(result -> {
switch (result.getCode()) {
case HttpCode.CODE_SUCCESS: {
return createData(result.getData());
}
case HttpCode.CODE_TOKEN_INVALID: {
throw new TokenInvalidException();
}
case HttpCode.CODE_ACCOUNT_INVALID: {
throw new AccountInvalidException();
}
default: {
throw new ServerResultException(result.getCode(), result.getMsg());
}
}
});
}
flatMap
代码
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
return flatMap(mapper, false);
}
Observerable
的类的实现类:
public abstract class Observable<T> implements ObservableSource<T> {
}
ObservableSource
类:
public interface ObservableSource<T> {
/**
* Subscribes the given Observer to this ObservableSource instance.
* @param observer the Observer, not null
* @throws NullPointerException if {@code observer} is null
*/
void subscribe(@NonNull Observer<? super T> observer);
}
ObservableTransformer
的代码:
public interface ObservableTransformer<Upstream, Downstream> {
/**
* Applies a function to the upstream Observable and returns an ObservableSource with
* optionally different element type.
* @param upstream the upstream Observable instance
* @return the transformed ObservableSource instance
*/
@NonNull
ObservableSource<Downstream> apply(@NonNull Observable<Upstream> upstream);
}
我试着在写了BaseFragment:Fragment(),IUIActionEventObserver
{
override val lContext: Context?
get() = context
override val lLifecycleOwner: LifecycleOwner
get() = this
override val lifecycleSupportedScope: CoroutineScope
get() = lifecycleScope
}
这种写法正常用没问题,可是会出现内存泄漏问题,麻烦问一下怎么处理
如题,在项目里没有看到网络请求的手动释放,虽然是使用livedata,但是不是还需要rxjava操作手动释放一下请求呢?
package com.ling.kotlin.retroft.converter
import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.reflect.TypeToken
import com.ling.kotlin.rf.BaseResponse
import com.ling.kotlin.rf.retroft.HttpConfig
import com.ling.kotlin.rf.retroft.ServerResultException
import com.ling.kotlin.rf.retroft.TokenInvalidResultException
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import okhttp3.internal.Util.UTF_8
import okio.Buffer
import retrofit2.Converter
import retrofit2.Retrofit
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.lang.reflect.Type
import java.nio.charset.Charset
/**
自定义gson解析,主要是解析服务器返回失败的json数据
如下:
服务器数据返回成功如下:{"status":1,"msg":"请求成功","data":{……}}
失败如下:{"code":403,"msg":"请求TOKEN失效","data":{},"status":"error","error":false}
*/
class GsonConvertFactory private constructor(private val gson: Gson) : Converter.Factory() {
init {
if (gson == null) throw NullPointerException("gson == null")
}
override fun requestBodyConverter(type: Type?, parameterAnnotations: Array?, methodAnnotations: Array?, retrofit: Retrofit?): Converter<*, RequestBody>? {
val adapter = gson.getAdapter(TypeToken.get(type))
return GsonRequestBodyConverter(gson, adapter)
}
override fun responseBodyConverter(type: Type?, annotations: Array?, retrofit: Retrofit?): CustomGsonResponseBodyConverter {
val adapter = gson.getAdapter(TypeToken.get(type))
return CustomGsonResponseBodyConverter(gson, adapter)
}
companion object {
fun create(gson: Gson = Gson()): GsonConvertFactory {
return GsonConvertFactory(gson)
}
}
}
/**
未修改跟原来的
GsonConverterFactory #GsonResponseBodyConverter一样的
*/
class GsonRequestBodyConverter(private val gson: Gson, private val adapter: TypeAdapter) : Converter<T, RequestBody> {
@throws(IOException::class)
override fun convert(value: T): RequestBody {
val buffer = Buffer()
val writer = OutputStreamWriter(buffer.outputStream(), UTF_8)
val jsonWriter = gson.newJsonWriter(writer)
adapter.write(jsonWriter, value)
jsonWriter.close()
return RequestBody.create(MEDIA_TYPE, buffer.readByteString())
}
companion object {
private val MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8")
private val UTF_8 = Charset.forName("UTF-8")
}
}
/**
*
自定义响应类 修改做拦截抛出操作 应用到Gson反序列和序列化部分的知识
跟比原来的了一个拦截器,方便实现自定义业务的要求
*/
class CustomGsonResponseBodyConverter(private val gson: Gson, private val adapter: TypeAdapter) : Converter<ResponseBody, T> {
@throws(IOException::class)
override fun convert(value: ResponseBody): T {
val response = value.string()
val httpStatus = gson.fromJson(response, BaseResponse::class.java)
//token 失效,报错token失效异常
if(httpStatus.code == HttpConfig.CODE_TOKEN_INVALID){
value.close()
throw TokenInvalidResultException(httpStatus.msg ?: "token失效,请重新登陆",httpStatus.code)
}
//其他错误信息
if(httpStatus.code != HttpConfig.CODE_SUCCESS){
value.close()
throw ServerResultException(httpStatus.msg ?: "未知错误",httpStatus.code)
}
//继续处理body数据反序列化,注意value.string() 不可重复使用
val contentType = value.contentType()
val charset = if (contentType != null) contentType.charset(UTF_8) else UTF_8
val inputStream = ByteArrayInputStream(response.toByteArray())
val reader = InputStreamReader(inputStream, charset)
val jsonReader = gson.newJsonReader(reader)
value.use { value ->
return adapter.read(jsonReader)
}
}
}
请求默认在主线程?
fun <DataA, DataB> enqueue(apiFunA: suspend Api.() -> IHttpWrapBean,
apiFunB: suspend Api.() -> IHttpWrapBean,
showLoading: Boolean = false,
callbackFun: (RequestPairCallback<DataA, DataB>.() -> Unit)? = null): Job {
return launchMain {
val callback = if (callbackFun == null) null else RequestPairCallback<DataA, DataB>().apply {
callbackFun.invoke(this)
}
try {
if (showLoading) {
showLoading(coroutineContext[Job])
}
// callbackFun()
callback?.onStart?.invoke()
val responseList: List<IHttpWrapBean<out Any?>>
try {
responseList = listOf(
// requestLogin()
async { apiFunA.invoke(getApiService()) },
async { apiFunB.invoke(getApiService()) }
).awaitAll()
val failed = responseList.find { it.httpIsFailed }
if (failed != null) {
throw ServerCodeBadException(failed)
}
} catch (throwable: Throwable) {
handleException(throwable, callback)
return@launchMain
}
onGetResponse(callback, responseList)
} finally {
try {
callback?.onFinally?.invoke()
} finally {
if (showLoading) {
dismissLoading()
}
}
}
}
}
看到Repo类和viewMode也用liveData传值,ViewMode持有了LifecycleOwner,是不是不合理,直接用回调传值就行了
同步更新java版本呀,2.0 kotlin版本都是一个完整的天气app了,java版本落后了呀
如题
每完成一个类型的接口请求,都要实现很多的类,这样来看,Repo是否就没有必要存在?毕竟DataSource就足矣承担任务。当然,如果这个类型的接口较为复杂的话,Repo的存在也是有必要的,比如还存在paging
有什么办法可以获取code值?
网络请求页面关闭,请求还没回调回来的情况怎么处理呢
很好的学些框架封装,可让我重构项目中采用你的思路,谢谢作者,不合理的地方或者有好的建议一定会跟作者说明
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.