TL;博士
考虑到有关启动器屏幕和开始目的地导航的新建议,我们应该如何使用 Jetpack 导航和 RxJava 将登录逻辑优雅地集成到 Android 应用程序中?
遵循导航原则,我的应用应具有固定的开始/退出屏幕。让我们称之为主屏幕。
考虑到对此屏幕的访问仅适用于已登录用户(与除LoginFragment
外的所有其他屏幕一样(,我应该将逻辑放在何处以及如何放置逻辑以检查"我的用户是否已登录?否,导航到LoginFragment
"?
我的应用程序分为几层(洋葱架构(。我在我的Remote layer
中注入了一个SessionManager
POJO,持有Remote layer
中使用的令牌和其他会话相关信息。 我还有一个用户存储库,用于我的登录用户用例,它将填充/更新SessionManager
。
我不希望每个用例或每个演示者都检查用户是否已登录,因为这不是他们关心的问题(对吧?我应该何时以及如何检查我的用户是否已登录? 在持有导航组件的MainActivity
?如何在使用 RxJava 时正确更改导航(因此对检查的响应是异步的(?
问题
我应该在启动画面/启动器中执行此操作吗?该启动器应该是一个单独的活动(与新的单个活动建议冲突(,还是应该成为我的导航的一部分?我是否应该在我的应用程序OnCreate中进行检查,并延迟我的主活动的启动?每个演示者是否应该编写用例,首先调用"我是否登录了?"然后调用"做事"?
谢谢!
我知道有很多解决方案。这是我的两分钱。
在应用程序类中,使用子组件来表示应用的登录状态。比方说,这userComponent
为需要用户帐户的所有内容(例如用户名、凭据、经过身份验证的 API 客户端(添加用户范围的绑定。然后确保所有片段(登录片段除外(都使用此组件注入。这可能是您的应用程序类:
class MyApplication : Application() {
private lateinit var appComponent: AppComponent
private var userComponent: UserComponent? = null
...
}
在初始启动时,您的主活动将检查登录状态(userComponent == null
(,并在必要时导航到登录片段。然后,成功的身份验证应生成userComponent
并使用用户详细信息为其设定种子。然后导航到任何其他片段时,它有权访问此子组件及其所有绑定。若要稍后注销,请设置userComponent = null
并导航离开用户片段。
class MyApplication : Application() {
...
fun signIn(account: Account) {
userComponent = appComponent.userComponent().account(account).build()
}
fun signOut() {
userComponent = null
}
}
要在第二次应用程序启动时跳过登录,请尝试在应用程序的onCreate
中登录用户(构建userComponent
(。然后,您的单个主活动将立即导航到例如您的主页片段。
对于 dagger.android 用户:从您的userComponent
获取fragmentInjector
,以便AndroidSupportInjection.inject(this)
访问用户范围的绑定。
class MyApplication : Application(), HasSupportFragmentInjector {
private var fragmentInjector: DispatchingAndroidInjector<Fragment>? = null
...
fun signIn(account: Account) {
userComponent = appComponent.userComponent().account(account).build()
fragmentInjector = userComponent.fragmentInjector()
}
override fun supportFragmentInjector() = fragmentInjector!!
...
}
希望这个答案对您有所帮助!