kotlin之jetpack+mvvm+rxjava+retrofit

1 篇文章 0 订阅
1 篇文章 0 订阅

kotlin之jetpack+mvvm+rxjava+retrofit

最近在做新项目,看到kotlin语言,于是对着菜鸟教程看了一下,准备新项目使用kotlin写:

技术组合

1 网络请求框架okHttp 目前对于okhttp支持的比较好的是retrofit框架
2 异步处理采用的是rxjava框架,目前虽然rxjava3.0出来了,但是retrofit目前还没有更新到3.0 所以采用 的还是rxjava2.0。
3.对于项目整体框架采用的是mvvm思想,因为使用的是谷歌推荐的jetpack,有兴趣的同学可以去了解一下;
下面贴部分代码:

abstract class BaseFragmeent<VM : AndroidViewModel?, SV : ViewDataBinding?> : Fragment() {
    protected var viewModel: VM? = null
    protected var bindingView: SV? = null

    // fragment是否显示了
    protected var mIsVisible = false

    //MVVM是否准备好了
    protected var mIsPrepared = false

    //是否是第一次加载
    protected var mIsFirst = true

    private var activity: Activity? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        activity = context as Activity
    }

    @Nullable
    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        bindingView = DataBindingUtil.inflate<SV>(activity?.layoutInflater!!, setContent(), null, false)
        return bindingView?.root
    }

    override fun onActivityCreated(@Nullable savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initViewModel()
    }

    /**
     * 初始化ViewModel
     */
    private fun initViewModel() {
        val viewModelClass = ClassUtil.getViewModel<VM>(this)
        if (viewModelClass != null) {
            viewModel = activity?.application?.let {
                ViewModelProvider.AndroidViewModelFactory(it)
                        .create(viewModelClass)
            }
        }
    }

    protected open fun <T : View?> getView(id: Int): T {
        return view?.findViewById<View>(id) as T
    }

    /**
     * 布局
     */
    abstract fun setContent(): Int

}
abstract class BaseActivity<VM : AndroidViewModel?, SV : ViewDataBinding?> : AppCompatActivity() {
    // ViewModel
    protected var viewModel: VM? = null

    // 布局view
    protected var bindingView: SV? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //初始化沉浸式
        if (isImmersionBarEnabled()) {
            initImmersionBar()
        }
    }


    override fun setContentView(@LayoutRes layoutResID: Int) {
        bindingView = DataBindingUtil.inflate<SV>(layoutInflater, layoutResID, null, false)
        window.setContentView(bindingView!!.root)
        initViewModel()
    }

    /**
     * 初始化ViewModel
     */
    private fun initViewModel() {
        val viewModelClass= ClassUtil.getViewModel<VM>(this)
        if (viewModelClass != null) {
            viewModel = ViewModelProvider.AndroidViewModelFactory(application)
                    .create(viewModelClass)
        }
    }


    /**
     * 是否可以使用沉浸式
     * Is immersion bar enabled boolean.
     *
     * @return the boolean
     */
    protected open fun isImmersionBarEnabled(): Boolean {
        return false
    }

    protected open fun initImmersionBar() {
        //在BaseActivity里初始化
        ImmersionBar.with(this).navigationBarEnable(false).init()
    }

}
open class BaseViewModel(application: Application) : AndroidViewModel(application) {
    private var mCompositeDisposable: CompositeDisposable? = null
    protected var apiService = RetrofitManager.apiService
    var error = MutableLiveData<String>()
        protected set

    protected fun <T : BaseRes<*>> execute(observable: Observable<T>, subscriberCallBack: SubscriberCallBack<T>)  {
        observable
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriberCallBack)
    }

    protected fun addDisposable(disposable: Disposable?) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = CompositeDisposable()
        }
        mCompositeDisposable!!.add(disposable!!)
    }

    override fun onCleared() {
        super.onCleared()
        if (mCompositeDisposable != null && !mCompositeDisposable!!.isDisposed) {
            mCompositeDisposable!!.clear()
        }
    }
}
class RetrofitManager private constructor(url: String) {
    private val mApiService: APIService

    init {
        initOkHttpClient()
        val retrofit = Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(mOkHttpClient)
                .build()
        mApiService = retrofit.create(APIService::class.java)
    }

    companion object {
        //时间超时
        const val TIMEOUT = 10

        @Volatile
        private var mOkHttpClient: OkHttpClient? = null

        //保证多个地址的;
        var managers: MutableMap<String, RetrofitManager> = HashMap()
        private const val release_url = "http://ytai-api.test.ytzxjy.com/"
        private const val debug_url = ""

        //
        fun getInstance(url: String): RetrofitManager {
            var instance = managers[url]
            if (instance == null) {
                instance = RetrofitManager(url)
                managers[url] = instance
            }
            return instance
        }

        val instance: RetrofitManager
            get() = getInstance(release_url)

        @JvmStatic
        val apiService: APIService
            get() = instance.mApiService

        fun getAPIService(url: String): APIService {
            return getInstance(url).mApiService
        }
    }


    private fun initOkHttpClient() {
        val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
            private val mMessage = StringBuilder()
            override fun log(message: String) {
                var message = message
                if (LogUtil.isDebug) {
                    // 请求或者响应开始
                    if (message.startsWith("--> POST")) {
                        mMessage.setLength(0)
                    }
                    // 以{}或者[]形式的说明是响应结果的json数据,需要进行格式化
                    if (message.startsWith("{") && message.endsWith("}")
                            || message.startsWith("[") && message.endsWith("]")
                    ) {
                        message = JsonUtil.formatJson(JsonUtil.decodeUnicode(message))
                    }
                    mMessage.append(message)
                    // 响应结束,打印整条日志
                    if (message.startsWith("<-- END HTTP")) {
                        LogUtil.i("message==",mMessage.toString())
                    }
                }
            }
        })
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        if (mOkHttpClient == null) {
            synchronized(RetrofitManager::class.java) {
                if (mOkHttpClient == null) {
                    // 指定缓存路径,缓存大小100Mb
                    val cache = Cache(
                            File(App.app.applicationContext.cacheDir, "HttpCache"),
                            1024 * 1024 * 100
                    )
                    mOkHttpClient = OkHttpClient.Builder()
                            .cache(cache) //统一处理请求头
                            .addInterceptor(interceptor)
                            .retryOnConnectionFailure(false) //错误重连
                            .connectTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) //设置超时
                            .readTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
                            .writeTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
                            .build()
                }
            }
        }
    }
class SubscriberCallBack<T : BaseRes<*>?>(private val apiCallback: ApiCallback<T>) : Observer<T> {
    override fun onError(e: Throwable) {
        e.printStackTrace()
        if (e is HttpException) {
            val httpException = e
            var msg = httpException.message
            val code = httpException.code()
            try {
                msg = httpException.response().toString()
            } catch (e1: IOException) {
                e1.printStackTrace()
            }
            msg = if (code == 408) {
                "服务器响应超时,请稍后再试。code=${code}msg=$msg"
            } else if (code == 405) {
                "请求行中指定的请求方法不能被用于请求相应的资源。code=${code}msg=$msg"
            } else if (code == 403) {
                "服务器已经理解请求,但是拒绝执行它。code=${code}msg=$msg"
            } else if (code == 500) {
                "服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。code=${code}msg=$msg"
            } else if (code == 404) {
                "请求失败,请求所希望得到的资源未被在服务器上发现。code=${code}msg=$msg"
            } else {
                "code=" + code + "msg=" + msg
            }
            apiCallback.onFailure(code, msg)
        } else if (e is SocketTimeoutException) {
            val msg = "连接服务器超时"
            apiCallback.onFailure(408, msg)
        } else if (e is ConnectException) {
            val msg = "网络中断,请检查您的网络状态"
            apiCallback.onFailure(408, msg)
        } else if (e is TimeoutException) {
            val msg = "连接超时,请检查您的网络状态"
            apiCallback.onFailure(408, msg)
        } else {
//            apiCallback.onFailure(0, e.getMessage());
            apiCallback.onFailure(0, "未知错误")
        }
        apiCallback.onCompleted()
    }


    override fun onSubscribe(disposable: Disposable) {
        apiCallback.onSubscribe(disposable)
    }

    override fun onNext(response: T) {
        apiCallback.onSuccess(response)
    }

    override fun onComplete() {

    }


}

目前核心类就是这几个吧,其他都是一些回调,调用的简单业务,有兴趣的可以一起交流交流。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jetpack是一个结合MVVM的快速开发框架,它基于MVVM模式并集成了谷歌官方推荐的Jetpack组件库,包括LiveData、ViewModel、Lifecycle和Navigation组件。这个框架使用Kotlin语言,并添加了大量的拓展函数,以简化代码。它还集成了Retrofit网络请求和协程,可以帮助开发者快速开发项目。\[1\] MVVM是一种软件架构模式,它将应用程序分为三个主要部分:模型(Model)、视图(View)和视图模型(ViewModel)。在MVVM中,视图负责显示数据和用户交互,模型负责处理数据和业务逻辑,而视图模型则充当视图和模型之间的中间层,负责管理视图的状态和数据。JetpackMVVM模式可以帮助开发者更好地组织和管理代码,提高开发效率和舒适度。\[1\] 使用JetpackMVVM可以带来许多好处,例如简化代码、提高开发效率、提供更好的代码结构和可维护性。通过使用Jetpack的组件库,开发者可以更轻松地处理生命周期管理、数据共享和导航等常见任务。而MVVM模式则可以帮助开发者更好地分离关注点,使代码更易于测试和维护。\[2\] 总之,JetpackMVVM是一种强大的组合,可以帮助开发者快速开发Android应用程序,并提供更好的代码结构和可维护性。如果你想了解更多关于JetpackMVVM的信息,可以参考引用\[1\]中提供的Jetpack框架的介绍。 #### 引用[.reference_title] - *1* *2* [JetpackMvvm](https://blog.csdn.net/u014608640/article/details/124711159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid...](https://blog.csdn.net/m0_37796683/article/details/130277908)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值