Android 之Kotlin使用Retrofit和RxJava实现网络请求

一、实现原理

    使用Retrofit实现网络请求,在通过Rxjava2实现线程调度,通过Gson得到当前的需要的模型类

二、实现过程

1、添加依赖

    implementation 'com.squareup.okhttp3:okhttp:3.12.3' // OkHttp3
    implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' // 日志
    implementation 'com.squareup.retrofit2:retrofit:2.6.0' // Retrofit2
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.0' //  Retrofit2 -> RxJava 的适配
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0' // Gson转换器
    implementation 'com.squareup.retrofit2:converter-scalars:2.4.0' // 响应转为基本类型所需依赖
// LeakCanary 内存泄漏检测工具
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
    debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
    // RxJava
    implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

    // 处理网络请求可能导致的内存泄漏
    implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'

 2、添加对应的权限

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3、创建对应的基础类目录

三、实现

1、因为使用了RxJava2所以需要使用Rxlifecycle防止内存泄露

2、实现Activity和Fragment的基类,并根据自己的需要做简单的封装

abstract class BasicActivity : RxFragmentActivity() {
    protected abstract val mLayoutResId: Int

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (this.mLayoutResId > 0) {
            setContentView(mLayoutResId)
        } else {
            throw RuntimeException("this activity is miss cotentview")
        }
        onContentViewReady(savedInstanceState)

    }

    abstract fun onContentViewReady(savedInstanceState: Bundle?)

    fun <A> startActivity(clazz: Class<A>, data: Bundle?) {
        var intent = Intent(this, clazz)
        data?.let { intent.putExtras(data) }
        this.startActivity(intent)
    }

    fun <A> startActivity(clazz: Class<A>) {
        var intent = Intent(this, clazz)
        this.startActivity(intent)
    }
}
 
abstract class BasicFragment : Fragment(), LifecycleProvider<FragmentEvent> {
    private val lifecycleSubject = BehaviorSubject.create<FragmentEvent>()
    protected abstract val mLayoutResId: Int
    protected var mRootView: View? = null

    override fun lifecycle(): Observable<FragmentEvent> {
        return this.lifecycleSubject.hide()
    }

    /**
     * 指定生命周期断开
     */
    override fun <T : Any?> bindUntilEvent(event: FragmentEvent): LifecycleTransformer<T> {
        return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event)
    }

    /**
     * 绑定生命周期到lifecycle
     */
    override fun <T : Any?> bindToLifecycle(): LifecycleTransformer<T> {
        return RxLifecycleAndroid.bindFragment(this.lifecycleSubject)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.lifecycleSubject.onNext(FragmentEvent.CREATE)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (null != this.mRootView) {
            var parent = this.mRootView!!.parent
            if (null != parent) {
                (parent as ViewGroup).removeView(this.mRootView)
            }
        } else {
            this.mRootView = inflater.inflate(this.mLayoutResId, container, false)
        }

        return this.mRootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        this.lifecycleSubject.onNext(FragmentEvent.CREATE_VIEW)
    }

    private var mIsCalled = false
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        if (!this.mIsCalled) {
            this.mIsCalled = true
            onContentReady(savedInstanceState)
        }
    }

    private var mContext: Context? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.mContext = context
        this.lifecycleSubject.onNext(FragmentEvent.ATTACH)
    }

    override fun onStart() {
        super.onStart()
        this.lifecycleSubject.onNext(FragmentEvent.START)
    }

    override fun onResume() {
        super.onResume()
        this.lifecycleSubject.onNext(FragmentEvent.RESUME)
    }

    override fun onPause() {
        super.onPause()
        this.lifecycleSubject.onNext(FragmentEvent.PAUSE)
    }

    override fun onStop() {
        super.onStop()
        this.lifecycleSubject.onNext(FragmentEvent.STOP)
    }

    override fun onDestroy() {
        super.onDestroy()
        this.lifecycleSubject.onNext(FragmentEvent.DESTROY)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        this.lifecycleSubject.onNext(FragmentEvent.DESTROY_VIEW)
    }

    override fun onDetach() {
        super.onDetach()
        this.lifecycleSubject.onNext(FragmentEvent.DETACH)
    }

    override fun getContext(): Context? {
        var context = super.getContext()
        if (null == context) context = this.mContext
        return context
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
    }

    /**
     * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     * 自己的方法
     */

    abstract fun onContentReady(savedInstanceState: Bundle?)

    fun <A> startActivity(clazz: Class<A>, data: Bundle?) {
        this.mContext?.let {
            var intent = Intent(it, clazz)
            data?.let { intent.putExtras(data) }
            this.startActivity(intent)
        }

    }

    fun <A> startActivity(clazz: Class<A>) {

        this.mContext?.let {
            var intent = Intent(it, clazz)
            this.startActivity(intent)
        }

    }
}
3、因为Retrofit的网络请求是OkHttp实现的,所以网络请求还是相当于封装OkHttp
class HttpRequest<ApiService> {
    //请求超时时间5S
    private val connectionTimeoutTime = 60L
    private val httpLoggingInterceptor = HttpLoggingInterceptor().setLevel(

        HttpLoggingInterceptor.Level.BODY
//        else HttpLoggingInterceptor.Level.NONE
    )

    //构造OkhttpBuilder
    private val okhttBuilder: OkHttpClient.Builder =
        OkHttpClient.Builder()
            .addNetworkInterceptor(httpLoggingInterceptor)
            .addInterceptor(LogInterceptor())
                //链接超时设置
            .connectTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
            //读取超时时间设置
            .readTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
            .writeTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
            //默认重试一次,若需要重试N次,则要实现拦截器。
            .retryOnConnectionFailure(true)



    class LogInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            var request = chain.request()
            Log.i(
                "wxf",
                " Requeste " + "\nmethod:" + request.method() + "\nurl:" + request.url() + "\nbody:" + request.body().toString()
            )


            var response = chain.proceed(request)
            Log.i(
                "wxf",
                " Response " + "\nsuccessful:" + response.isSuccessful + "\nbody:" + response.peekBody(
                    1024
                )?.string()
            )

            return response
        }

    }

    /**
     * 发起网络请求
     */
    private fun buildOkHttpClient(): OkHttpClient {
        return this.okhttBuilder.build()
    }

    /**
     * 构建ApiService
     */
    fun buildApiService(apiService: Class<ApiService>, baseurl: String): ApiService {
        return Retrofit
            .Builder()
            .client(buildOkHttpClient())
            .baseUrl(baseurl)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build().create(apiService)
    }

}

 

/**
 * 负责与服务器接口通信
 */
open class ApiRequest(private val progress: HttpObserver.Progress?) {
    /**
     * 服务器api响应实体类
     */
    protected fun <Entity> request(
        observable: Observable<Entity>,
        lifecycleTransformer: LifecycleTransformer<Entity>,
        callback: ResponseCallback<Entity>
    ) {
        observable.compose(lifecycleTransformer)
            .subscribeOn(Schedulers.io())//线程调度,发射事件的线程
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())//订阅者接收事件的线程
            .subscribe(createHttpObserver(callback))//订阅


    }

    protected open fun <Entity> createHttpObserver(callback: ResponseCallback<Entity>): HttpObserver<Entity> {

        return DefaultHttpObserver(callback, progress)
    }

}

 4、解析得到数据

class DefaultListResponseParse<Entity>(
    private val callback: ResponseCallback<List<Entity>>,
    private val entityClass: Class<Entity>
) : ResponseCallback<String> {

    private val gson: Gson = Gson()

    override fun onSuccess(response: String?) {
        val basicEntity = parseResponse(response)

        if (null != basicEntity) {
            if (basicEntity.code == BasicResponse.CODE_SUCCESS) {
                this.callback.onSuccess(parseEntitys(basicEntity))
            }
        } else {
            onServerException()
        }

    }


    override fun onFailed(ex: RequestException) {

    }

    private fun parseEntitys(response: BasicStringResponse?): List<Entity> {
        val entitys = arrayListOf<Entity>()
        if (!TextUtils.isEmpty(response?.ret)) {
            var jsonArray: JSONArray? = null

            try {
                jsonArray = JSONArray(response?.ret)
            } catch (e: Exception) {
            }
            if (null != jsonArray) {
                Log.i("wxf", "array->" + jsonArray)
                for (index in 0..(jsonArray.length() - 1)) {
                    var entity: Entity? = null
                    try {
                        entity = this.gson.fromJson(jsonArray.optString(index), entityClass)
                    } catch (e: Exception) {

                    }

                    if (null != entity) {
                        entitys.add(entity)
                    }
                }
            }
        }

        return entitys
    }

    private fun parseResponse(response: String?): BasicStringResponse? {
        var basicEntity: BasicStringResponse? = null
        var jsonObject: JSONObject? = null

        if (!TextUtils.isEmpty(response)) {
            try {
                jsonObject = JSONObject(response)
            } catch (e: Exception) {
            }
            if (null != jsonObject) {
                basicEntity = BasicStringResponse()
                basicEntity.code = jsonObject.optInt("code")
                basicEntity.msg = jsonObject.optString("msg")
                basicEntity.ret = jsonObject.optString("ret")
            }

        }


        return basicEntity
    }

    private fun onServerException() {
        onFailed(ServerException())
    }
}
/**
 * 将得到的String转换成Entity
 */
class DefaultResponseParse<Entity>(
    private val callback: ResponseCallback<Entity>,
    private val entityClass: Class<Entity>
) : ResponseCallback<String> {
    private val gson: Gson = Gson()

    override fun onSuccess(response: String?) {
        Log.i("wxf","onSuccess"+response)
        var basicEntity = parseResponse(response)
        if (null != basicEntity) {
            if (basicEntity.code == BasicResponse.CODE_SUCCESS) {
                val entity = parseEntity(basicEntity.ret)
                Log.i("wxf", "entity:" + entity)
                this.callback.onSuccess(entity)
            } else {
                onFailed(RequestException(basicEntity.msg, basicEntity.errorCode.toInt()))
            }
        } else {
            onServerException()
        }
    }

    override fun onFailed(ex: RequestException) {
        this.callback.onFailed(ex)
    }

    private fun parseResponse(response: String?): BasicStringResponse? {
        var basicEntity: BasicStringResponse? = null
        var jsonObject: JSONObject?

        try {
            jsonObject = JSONObject(response)
        } catch (e: Exception) {
            jsonObject = null
        }

        if (jsonObject != null) {
            basicEntity = BasicStringResponse()
            basicEntity.code = jsonObject.optInt("code")
            basicEntity.msg = jsonObject.optString("msg")
            basicEntity.ret = jsonObject.optString("ret")
        }

        return basicEntity
    }

    private fun onServerException() = this.onFailed(ServerException())

    private fun parseEntity(data: String?): Entity? {
        var entity: Entity? = null
        try {
            if (!TextUtils.isEmpty(data)) {
                entity = this.gson.fromJson(data, this.entityClass)
            }
        } catch (e: Exception) {

        }

        return entity
    }

}

5、使用

  @POST("others/carousel")
    fun getBanner(): Observable<BasicResponse<List<HomeBanner>>>
class HomeApi(context: Context?) : ApiRequest(context.let { DefaultHttpProgress(context) }) {

    private val homeApiService =
        HttpRequest<HomeApiService>()
            .buildApiService(HomeApiService::class.java, Constool.BASE_URL)


    fun getBanner(
        lifecycleTransformer: LifecycleTransformer<BasicResponse<List<HomeBanner>>>,
        callback: ResponseCallback<BasicResponse<List<HomeBanner>>>
    ) {
        request(
            this.homeApiService.getBanner(),
            lifecycleTransformer, callback
        )
    }

}
    HomeApi(this).let {
            it.getBanner(
                this.bindToLifecycle(),
                object : ResponseCallback<BasicResponse<List<HomeBanner>>> {
                    override fun onSuccess(response: BasicResponse<List<HomeBanner>>?) {
                        response?.let {
                            Log.i("wxf", "getBanner->" + it.ret?.size)
                        }
                    }

                    override fun onFailed(ex: RequestException) {

                    }

                })
}

代码在我的下载资源中有,名字为KT_Retrofit_Rxjava2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值