Git Product home page Git Product logo

reactivehttp's Introduction

ReactiveHttp

一个基于 Kotlin + Jetpack + Coroutines + Retrofit 封装的网络请求框架

导入依赖

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

dependencies {
    implementation 'com.github.leavesCZY:ReactiveHttp:1.1.3'
}

更多介绍请看这里:wiki

reactivehttp's People

Contributors

leavesczy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactivehttp's Issues

【非bug】对RetrofitManagement中的一个方法实现感到不解

在阅读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);
}

如何在fragment中使用

我试着在写了BaseFragment:Fragment(),IUIActionEventObserver
{
override val lContext: Context?
get() = context

override val lLifecycleOwner: LifecycleOwner
    get() = this

override val lifecycleSupportedScope: CoroutineScope
    get() = lifecycleScope

}
这种写法正常用没问题,可是会出现内存泄漏问题,麻烦问一下怎么处理

扩展GsonconverterFactory,建议加入下面的类,做下拦截

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)
     }
    

    }
    }

感谢https://blog.csdn.net/Z_DingHao/article/details/78602950

多个请求 async 如何处理异常,try catch抓不到 会崩溃

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()
}
}
}
}
}

java版本请同步更新

同步更新java版本呀,2.0 kotlin版本都是一个完整的天气app了,java版本落后了呀

Repo层真的有必要存在吗

每完成一个类型的接口请求,都要实现很多的类,这样来看,Repo是否就没有必要存在?毕竟DataSource就足矣承担任务。当然,如果这个类型的接口较为复杂的话,Repo的存在也是有必要的,比如还存在paging

很好的学习框架封装

很好的学些框架封装,可让我重构项目中采用你的思路,谢谢作者,不合理的地方或者有好的建议一定会跟作者说明

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.