登录 MVP 改造

Login MVP with retrofit

你好,我正在尝试创建一个简单的应用程序,其中使用改造库调用 api 进行登录,我想使用 MVP 模式,你们中的任何人都可以吗关于如何做的指南,因为我已经搜索了很多并且发现了很多不同的解决方案,所以现在我想看看你的我的想法是什么:

网络 -改造实例 模型 -用户pojo 主持人 - 来自 activity 的电话 看法 - showProgressBar()、hideProgressBar()

等方法

但我不确定这是否是一个好方法...我也想检查何时失败,并且一切都井井有条。

对于 android 架构,目前谷歌推荐使用 MVVM 模式而不是 MVP,它具有 android 架构组件 (AAC)。 mvvm 优于 MVP 的原因有很多。以下是 MVP 模式的一些缺点。

回调地狱

  • MVP模式将业务逻辑和视图修改分离为 Presenter 和 View,它需要一个接口让视图能够 执行业务操作时与演示者交互 (eg.requesting data/uploading 数据)。视图需要实现这个 接口,演示者通常根据这个调用方法 向视图提供数据的接口。换句话说,MVP 使用 数据通道的回调。

    对于这些交互的每个动作,一个方法被添加到 界面。互动时很快就会变得势不可挡 因为会有两个很多的方法来维护。的一个变化 接口中的方法也导致两者的多个变化 由于此 MVP 的紧密耦合性质,演示者和视图。

配置更改

  • 当配置发生变化时,MVP 没有解决这个问题 (例如,显示指标变化、屏幕旋转等)。查看状态 在您明确处理之前不会持久化。

视图和演示者的紧密结合

  • 如前所述,在 MVP 中,view 和 presenter 是紧密耦合的, 在添加方法时,维护会很痛苦, 更改方法签名。

MVVM 模式通常更适合并且是一种更好的设计模式,因为它更易于维护。由于以下原因,我更喜欢 MVVM 而不是 MVP,

被动

  • MVVM是Model View ViewModel的简称,其中view model是一个 类似的抽象层展示者提供数据给 看法。当 viewModel 通知 view 时,View 观察 viewModel。 它确保视图始终获取最新数据。它避免 回调地狱只有一个地方,视图可以得到 数据,而视图始终依赖于它。

    MVVM 与反应模式配合得很好。举个例子,像你 说,改造通常与 Observable 模式一起使用(如 RxJava ) 在 MVVM 中。 retrofit 的客户住在 viewModel 中并检索数据 来自可以被视图观察到的 Observable 对象。一样可以 对于数据持久性和来自系统服务的数据也需要完成。

配置更改后的生存

  • ViewModel 通过让视图模型超出配置更改而幸存下来 视图的生命周期。在 viewModel 的实现中 AAC,它正是这样做的。当配置改变时,视图可以 始终从 viewModel 中检索状态,这提供了很多 更好的用户体验。

代码示例

在改造中,我们需要抓取一个改造客户端的实例。您应该通过单例/依赖注入来检索实例。这是来自 生产项目 的示例。下面的示例将使用 kotlin 代码,因为它很有趣。

创建实例,(注意使用了JSON转换器工厂MOSHI)

        Retrofit.Builder()
                .baseUrl("http://google.com")
                .addConverterFactory(MoshiConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(get("MockHttpClient"))
                .build().create<ApiService>(ApiService::class.java)

然后,需要为你使用的api定义一个接口,注意它return一个Flowable,它是一个Rxjava对象,类似于Observable,但有背压处理。现在只知道它是一个可观察的并且会发出数据。

interface ApiService {

    @FormUrlEncoded
    @POST(ACCESS_TOKEN_PATH)
    fun getAccessToken(
            @Field("client_id") client_id: String,
            @Field("client_secret") client_secret: String,
            @Field("grant_type") grant_type: String
    ): Flowable<GetAccessToken>
}

然后在你的 viewModel 中,为简单起见,我们可以直接注入这个实例/或从单例中检索它。(也可以添加存储库层以从源中检索数据)注意,这里使用实时数据作为viewmodel 和 view 之间的连接,它是一个 observable,会在 view 的生命周期结束时自行处置。

我们从 api 订阅可观察对象 return 并从中获取数据。

class TimeSettingViewModel(val context: Application, val retrofit: Retrofit) : AndroidViewModel(context) {

    private val compositeDisposable = CompositeDisposable()
    val accessTokenLiveData: MutableLiveData<AccessToken> = MutableLiveData()

    override fun onCleared() {
        compositeDisposable.clear()
        super.onCleared()
    }

    fun getAccessToken(){
        retrofit.getAccessToken("some","thing","here")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    accessTokenLiveData.value = it
                },{
                    it.printStackTrace()
                })

    }


}

稍后在您的视图(Activity/片段/其他基于视图的视图控制器)中,您可以在此处注入您的 viewModel 并观察其中的数据。根据这些数据,您可以更新您的观点。

private fun accessTokenLiveData() {
                timeSettingViewModel.accessTokenLiveData.observe(this, android.arch.lifecycle.Observer {
                    if (it != null) {
                        updateLoginView(it)
                    }
                })
                timeSettingViewModel.getAccessToken()
    }