使用kotlin+rxjava+retrofit对网络请求进行超简洁封装

依赖配置

    // 网络请求依赖
    implementation 'com.squareup.retrofit2:retrofit:2.6.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.6.1'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'

kotlin版本

ext.kotlin_version = '1.6.10'

实现思路

        为了使Activity、Fragment中的代码简洁,并减少业务或数据访问造成的代码侵入,最开始想通过MVP三层架构的形式进行分层,碍于小公司人少,MVP实现起来过于啰嗦。想到retrofit可以通过添加工件的方式使用Rxjava进行管理,但还是显得有些不够优雅。

改造前代码

        

package com.wandao.myapplication.fragments.settings

import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.wandao.myapplication.R
import com.wandao.myapplication.http.ServiceCreator
import com.wandao.myapplication.http.httpBean.CabinetList
import com.wandao.myapplication.http.httpService.CabinetService
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers

class BindCabinetFragment : Fragment() {
    val TAG = "BindCabinetFragment"
    var disposable : Disposable? = null
    var activity : AppCompatActivity? = null
    override fun onAttach(context: Context) {
        super.onAttach(context)
        activity = context as AppCompatActivity
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_bind_cabinet, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    private fun initView() {
        val observable = ServiceCreator.create<CabinetService>().getCabinetList()
        observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<CabinetList> {
                override fun onSubscribe(d: Disposable) {
                    Log.d(TAG, "onSubscribe: ")
                    disposable = d
                }

                override fun onNext(t: CabinetList) {
                    Log.d(TAG, "onNext: getCabinetList返回:"+t.toString())
                }

                override fun onError(e: Throwable) {
                    e.printStackTrace()
                }

                override fun onComplete() {
                    Log.d(TAG, "onComplete: ")
                }

            })
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy: ")
        disposable?.let {
            if (!it.isDisposed) it.dispose()
        }
    }
}

改造后

package com.wandao.myapplication.fragments.settings

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.wandao.myapplication.R
import com.wandao.myapplication.bean.MyEvents
import com.wandao.myapplication.config.RxBusCode
import com.wandao.myapplication.expand.getCabinetList
import com.wandao.myapplication.http.httpBean.CabinetList
import com.wandao.myapplication.utils.RxBus
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable

class BindCabinetFragment : Fragment() {
    val TAG = "BindCabinetFragment"
    var disposable : Disposable? = null
    var activity : AppCompatActivity? = null
    override fun onAttach(context: Context) {
        super.onAttach(context)
        activity = context as AppCompatActivity
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_bind_cabinet, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initView()
    }

    @SuppressLint("CheckResult")
    private fun initView() {
        //准备接收事件
        RxBus.getInstance().toObservable(this,MyEvents::class.java).observeOn(AndroidSchedulers.mainThread()).subscribe {
                when(it.code){
                    RxBusCode.HTTPDATAS ->{
                        val data = it.data as CabinetList
                        Log.d(TAG, "httpData's: $data")
                    }

                    RxBusCode.HTTPERROR ->{
                        val data = it.data as Throwable
                        Log.d(TAG, "httpError: ${data.printStackTrace()}")
                    }

                    RxBusCode.HTTPDISPOSABLE ->{
                        disposable = it.data as Disposable
                    }
                }
            }
        //发送请求事件
        activity?.getCabinetList()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy: ")
        disposable?.let {
            if (!it.isDisposed) it.dispose()
        }
    }
}

        最终通过kotlin的扩展函数,使在Activity和Fragment中不再需要关注网络请求的实现,并通过对Rxjava的二次封装,使网络请求从以前的调用变成发送,抽离重复代码,提高开发效率。

kotlin扩展函数

fun AppCompatActivity.getCabinetList(){
    RxjavaSendFactory.getInstance.sendObservable(ObserverFactory.getInstance.getCabinetList())
}
ObserverFactory
package com.wandao.myapplication.http

import com.wandao.myapplication.http.httpBean.CabinetList
import com.wandao.myapplication.http.httpService.CabinetService
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.annotations.NonNull
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers

class ObserverFactory private constructor(){

    companion object{
        val getInstance : ObserverFactory by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ObserverFactory()
        }
    }

    fun getCabinetList(): @NonNull Observable<CabinetList> {
        return observableThread(ServiceCreator.create<CabinetService>().getCabinetList())
    }

    fun <T>observableThread(observable: Observable<T>) : Observable<T>{
        return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
    }
}
RxjavaSendFactory
package com.wandao.myapplication.http

import com.wandao.myapplication.bean.MyEvents
import com.wandao.myapplication.config.RxBusCode
import com.wandao.myapplication.utils.RxBus
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable

class RxjavaSendFactory private constructor(){

    companion object{
        val getInstance : RxjavaSendFactory by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            RxjavaSendFactory()
        }
    }

    fun <T> sendObservable(observable: Observable<T>){

        observable.subscribe(object : Observer<T>{
            override fun onSubscribe(d: Disposable) {
                RxBus.getInstance().post(MyEvents(RxBusCode.HTTPDISPOSABLE,"",d))
            }

            override fun onNext(t: T) {
                RxBus.getInstance().post(MyEvents(RxBusCode.HTTPDATAS,"",t))
            }

            override fun onError(e: Throwable) {
                RxBus.getInstance().post(MyEvents(RxBusCode.HTTPERROR,"",e))
            }

            override fun onComplete() {}
        })

    }

}
RxBus(基于Rxjava2.0版本实现)
//RxJava    
implementation 'io.reactivex.rxjava2:rxjava:2.2.9' 
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
// 使用Android生命周期作为提供者
implementation 'com.trello.rxlifecycle2:rxlifecycle-android-lifecycle:2.2.2'
package com.wandao.myapplication.utils;

import android.annotation.SuppressLint;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import com.trello.lifecycle2.android.lifecycle.AndroidLifecycle;
import com.trello.rxlifecycle2.LifecycleProvider;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;

public class RxBus {
    private volatile static RxBus mDefaultInstance;
    private final Subject<Object> mBus;

    private final Map<Class<?>, Object> mStickyEventMap;

    private RxBus() {
        mBus = PublishSubject.create().toSerialized();
        mStickyEventMap = new ConcurrentHashMap<>();
    }

    public static RxBus getInstance() {
        if (mDefaultInstance == null) {
            synchronized (RxBus.class) {
                if (mDefaultInstance == null) {
                    mDefaultInstance = new RxBus();
                }
            }
        }
        return mDefaultInstance;
    }

    /**
     * 发送事件
     */
    @SuppressLint("CheckResult")
    public void post(Object event) {
        mBus.onNext(event);
    }

    /**
     * 使用Rxlifecycle解决RxJava引起的内存泄漏
     */
    public <T> Observable<T> toObservable(LifecycleOwner owner, final Class<T> eventType) {
        LifecycleProvider<Lifecycle.Event> provider = AndroidLifecycle.createLifecycleProvider(owner);
        return mBus.ofType(eventType).compose(provider.<T>bindToLifecycle());
    }

    /**
     * 判断是否有订阅者
     */
    public boolean hasObservers() {
        return mBus.hasObservers();
    }

    public void reset() {
        mDefaultInstance = null;
    }


    /**
     * Stciky 相关
     */

    /**
     * 发送一个新Sticky事件
     */
    public void postSticky(Object event) {
        synchronized (mStickyEventMap) {
            mStickyEventMap.put(event.getClass(), event);
        }
        post(event);
    }

    /**
     * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
     * 使用Rxlifecycle解决RxJava引起的内存泄漏
     */
    public <T> Observable<T> toObservableSticky(LifecycleOwner owner,final Class<T> eventType) {
        synchronized (mStickyEventMap) {
            LifecycleProvider<Lifecycle.Event> provider = AndroidLifecycle.createLifecycleProvider(owner);
            Observable<T> observable = mBus.ofType(eventType).compose(provider.<T>bindToLifecycle());
            final Object event = mStickyEventMap.get(eventType);

            if (event != null) {
                return observable.mergeWith(Observable.create(new ObservableOnSubscribe<T>() {
                    @Override
                    public void subscribe(ObservableEmitter<T> subscriber) throws Exception {
                        subscriber.onNext(eventType.cast(event));
                    }
                }));
            } else {
                return observable;
            }
        }
    }

    /**
     * 根据eventType获取Sticky事件
     */
    public <T> T getStickyEvent(Class<T> eventType) {
        synchronized (mStickyEventMap) {
            return eventType.cast(mStickyEventMap.get(eventType));
        }
    }

    /**
     * 移除指定eventType的Sticky事件
     */
    public <T> T removeStickyEvent(Class<T> eventType) {
        synchronized (mStickyEventMap) {
            return eventType.cast(mStickyEventMap.remove(eventType));
        }
    }

    /**
     * 移除所有的Sticky事件
     */
    public void removeAllStickyEvents() {
        synchronized (mStickyEventMap) {
            mStickyEventMap.clear();
        }
    }

}
MyEvents
package com.wandao.myapplication.bean

data class MyEvents<T>(
        var code : String,
        var message : String,
        var data : T
)

最终在Activity或Fragment中的调用方式,见改造后

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值