Kotlin-Android开发之MVP模式+Retrofit2.0+RxJava1.0+Dagger2框架封装

前言:上一篇文章讲了《Kotlin&Java-Android开发之MVP模式+Retrofit2.0框架封装》相信你看了之后,收货不少,所以这次在MVP+Retrofit的基础上增加RxJava和Dagger,都是现在比较流行的框架,如果你没有看上篇博客,从这篇开始也是一样,每个框架都会大致介绍一下,非常适合小白。注意:此篇博客使用的代码是Kotlin代码,如果你对Kotlin不熟悉,请移步我的《Kotlin快速入门


1.MVP模式:M(Model)即模型层,功能是提供数据,放在安卓中对应的是数据库、Beans、网络请求等。V(View)即视图层,功能是提供数据的展示,放在安卓中对应的是activity、fragment等。P(Presenter)即协调者,功能是负责主要逻辑功能的实现,将M和V进行联系起来,M和V彻底分离。

2.Retrofit2.0:基于Okhttp封装的,和RxJava搭配使用异常爽,总之很牛X,用就行了。这里有个简单的介绍,大家可以看一下《Android Retrofit2.0使用详解

3.RxJava1.0:现在已经出到2.0版本了,对于一个初学者来说,先接触1.0也是一样的,不管是1.0还是2.0核心思想都是观察者模式。这里有篇博客介绍的不错《RxJava2.0——从放弃到入门

4.Dagger2:Dagger是在编译时进行依赖注入的框架,在安卓中的体现比如在Activity、Fragment中会用到很多的类,实例化之后才能使用,这就导致Activity、Fragment依赖这些类,这样的程序耦合非常严重,这时候就需要有一个容器,将这些类放到这个容器里并实例化,用的时候去容器里面取就可以了,从依赖类到依赖这个容器,实现了解耦,这就是我所理解的依赖注入,即所谓控制反转;Dagger就是用来创造这个容器,所有需要被依赖的对象在Dagger的容器中实例化,并通过Dagger注入到合适的地方,实现解耦,MVP框架就是为解耦而生,因此MVP和Dagger是绝配;有兴趣的可以看下这个详细介绍《浅析Dagger2的使用


开始撸起代码。

1.先看下包的结构和要请求的json数据格式(数据来源聚合https://www.juhe.cn/大家注册个账户就行了)

2.新建一个Kotlin项目,然后添加依赖

    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.1.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
    implementation 'com.google.code.gson:gson:2.2.4'

    //dagger
    implementation 'com.google.dagger:dagger:2.6'
    kapt 'com.google.dagger:dagger-compiler:2.6'

    //rxjava
    implementation 'io.reactivex:rxjava:1.3.0'
    implementation 'io.reactivex:rxandroid:1.2.1'
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

不要忘记了在module下的gradle中添加

apply plugin: 'kotlin-kapt'

3.编写model层代码,进行retrofit的初始化和bean的编写(后续如有需要数据库的操作也是在这个模型层)

扫描二维码关注公众号,回复: 8586796 查看本文章
NetPresenter.kt
import retrofit2.Retrofit
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

open abstract class NetPresenter {
    val service: Service
    val url = "http://v.juhe.cn/toutiao/"
    init {
        val retrofit = Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build()
        service = retrofit.create<Service>(Service::class.java!!)
    }
}
Service.kt
import com.fly.mvpdemo.model.beans.ResponseInfo
import retrofit2.Call
import retrofit2.http.GET
import rx.Observable

interface Service {
    //使用Rxjava组合的接口
    @GET("index?type=caijing&key=自己申请")
    fun getMainInfoByRxjava(): Observable<ResponseInfo>
}
ResponseInfo.kt
data class ResponseInfo (
    var error_code: String,
    var reason: String,
    var result: Result
)

data class Result(
    var stat: String,
    var data: List<Data>
)
data class Data(
    var author_name: String,
    var category: String,
    var date: String,
    var thumbnail_pic_s: String,
    var title: String,
    var uniquekey: String,
    var url: String
)

4.编写P层的代码,在这一层使用的是rxjava。

MainActivityPresenter.kt

import android.util.Log
import com.fly.mvpdemo.model.beans.Data
import com.fly.mvpdemo.model.beans.ResponseInfo
import com.fly.mvpdemo.model.net.NetPresenter
import com.fly.mvpdemo.ui.MainActivity
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers

class MainActivityPresenter(val main: MainActivity) : NetPresenter() {

    /**
     * 使用异步获取数据
     */
    fun getMainInfo() {
        //RxJava使用
        val observable: Observable<ResponseInfo> = service.getMainInfoByRxjava()
        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                if (it == null){
                    Log.e("main", "服务器没有成功返回")
                }else{
                    if (it.error_code.equals("0")){
                        transmitDatas(it.result.data)
                    }else if (it.error_code.equals("-1")) {
                        //根据具体接口文档表示含义,比如定义-1为空数据
                        Log.e("main", "定义-1为空数据")
                    }
                }
            }, {
                Log.e("main", "Throwable"+ it.localizedMessage)
            }, {
                Log.e("main", "onComplete!");
            })
    }

    fun transmitDatas(datas: List<Data>) {
        //有数据,成功页面,刷新UI
        if (datas.isNotEmpty()) {
            main.onMainSuccess(datas)
        } else {
            //无数据,异常页面
            main.onMainFailed()
        }
    }
}

5.V层代码的编写,这里使用的比较简单,尽在Activity中Log打印一下访问的数据,在Activity中使用Dagger解耦V层和P层。

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.fly.mvpdemo.R
import com.fly.mvpdemo.dagger2.component.DaggerMainActivityComponent
import com.fly.mvpdemo.dagger2.module.MainActivityModule
import com.fly.mvpdemo.model.beans.Data
import com.fly.mvpdemo.presenter.MainActivityPresenter
import javax.inject.Inject

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var presenter: MainActivityPresenter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//        presenter = MainPresenter(this)
        //解耦View层和P层,通过dagger2(基于注解的依赖注入)生成MainActivityPresenter
        DaggerMainActivityComponent.builder().mainActivityModule(MainActivityModule(this)).build().inject(this)
        presenter.getMainInfo()
    }

    fun onMainSuccess(datas: List<Data>) {
        for (data in datas){
            Log.e("---",data.title)
        }
    }

    fun onMainFailed() {
    }
}

6.dagger包下代码的编写

MainActivityModule.kt
import com.fly.mvpdemo.presenter.MainActivityPresenter
import com.fly.mvpdemo.ui.MainActivity
import dagger.Module
import dagger.Provides

@Module class MainActivityModule(val mainActivity: MainActivity){

    @Provides fun provideMainActivityPresenter(): MainActivityPresenter {
        return MainActivityPresenter(mainActivity)
    }
}
MainActivityComponent.kt
import com.fly.mvpdemo.dagger2.module.MainActivityModule
import com.fly.mvpdemo.ui.MainActivity
import dagger.Component


@Component(modules = arrayOf(MainActivityModule::class)) interface MainActivityComponent {
    fun inject(mainActivity: MainActivity)
}

7.dagger2使用的注意事项:在编写完代码之后,要进行先Build之后,才能依赖注解。具体做法如下

(1)先把箭头指向的代码注释掉,因为此时还没有Build这样写是找不到Debug中的类

(2)进行Build,如图所示

(3)稍等片刻之后,就可以引用Debug中的类了

8.添加网络权限

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

9.运行截图


最后一句话,各位加油!

发布了105 篇原创文章 · 获赞 74 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/103956425