Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 干净的体系结构登录流_Android_Clean Architecture - Fatal编程技术网

Android 干净的体系结构登录流

Android 干净的体系结构登录流,android,clean-architecture,Android,Clean Architecture,我正在用一个干净的架构在我的Android应用程序中开发一个登录屏幕 成功使用登录时,我需要将令牌保存到共享首选项 在启动屏幕上,我需要检查用户是否登录 所以我的问题是,哪里是完美的地方: 保存令牌 我应该在LoginUseCase(域层)中保存令牌吗 与检查用户是否登录相同的问题。我应该将该操作作为用例吗?在我看来,在域层用例中执行该操作非常有意义。想象一下,在同一个项目中,您有另一个不同的模块用于电视应用程序。LoginPresenter可能与移动应用程序模块不同,但是,您可以重复使用相同的

我正在用一个干净的架构在我的Android应用程序中开发一个登录屏幕

成功使用登录时,我需要将令牌保存到共享首选项

在启动屏幕上,我需要检查用户是否登录

所以我的问题是,哪里是完美的地方:

  • 保存令牌
  • 我应该在LoginUseCase(域层)中保存令牌吗


    与检查用户是否登录相同的问题。我应该将该操作作为用例吗?

    在我看来,在域层用例中执行该操作非常有意义。想象一下,在同一个项目中,您有另一个不同的模块用于电视应用程序。
    LoginPresenter
    可能与移动应用程序模块不同,但是,您可以重复使用相同的用例。因此,在执行用例后,您不必知道为保存令牌而实现的每个
    LoginPresenter
    变体

    另一方面,我建议大家看看谷歌的员工是如何使用中的委托模式来面对登录过程的。在应用程序中使用可观察到的
    currentUser
    是一种非常常见的模式,它为您提供了很多优势。例如,尽管我不会将其标记为一个纯干净的体系结构参考项目,kickstarter的团队使用我所讨论的范例开发了一个有趣的
    MVVM+RxJava
    体系结构,这也值得一看

    class LoginUseCase(private val userRepository: UserRepository, private val schedulerProvider: SchedulerProvider) {
    
        fun execute(username: String, password: String): Single<Token> {
            return userRepository.login(username, password)
                .andThen(userRepository.saveToken(.....)
                .subscribeOn(schedulerProvider.getIOScheduler())
                .observeOn(schedulerProvider.getUIScheduler())
        }
    
    }
    
    class LoginPresenter(private val view: LoginContract.View,
                         private val setLoginStateUseCase: SetLoginStateUseCase,
                         private val loginUseCase: LoginUseCase,
                         private val schedulerProvider: SchedulerProvider): LoginContract.Presenter {
    
        private val compositeDisposable = CompositeDisposable()
    
        override fun performLogin(username: String, password: String) {
    
            if (username.isNullOrEmpty() || password.isNullOrEmpty()) {
                view.onShowLoginError("Field should not be empty")
            } else {
                view.showLoading()
                val disposable = loginUseCase.execute(username, password)
                        .subscribeOn(schedulerProvider.getIOScheduler())
                        .observeOn(schedulerProvider.getUIScheduler())
                        .andThen(setLoginStateUseCase.execute())
                        .subscribe({
                            view.hideLoading()
                            view.onLoginSuccess()
                        }, {error ->
                            view.hideLoading()
                            view.onShowLoginError(error.localizedMessage)
                        })
                compositeDisposable.add(disposable)
            }
        }