Cin*_*tiK 5 logic android structure flow accountmanager
我的app结构一直在苦苦挣扎.而且看起来这种结构在其他功能的开发中给我带来了很大的痛苦.所以在进一步讨论之前,我想提出一些建议,看看我在这里做错了什么.
我的应用程序的目的是连接到服务器,我使用AccountManager机制在设备上创建一个帐户并存储一个应该用于从服务器请求数据的令牌.在创建帐户时,一切都很好.(它也适用于设备设置 - >添加帐户)
它是这样的:
MainActivity是一种活动,当您启动应用程序时,检查您是否拥有帐户.如果您有一个帐户,我会在静态变量中获取令牌,以便MainActivity中的每个片段都可以访问它.(假设工作但不工作)另外,我使用LoginActivity创建一个intent来在设备上创建一个帐户.问题是我的片段无法获得此令牌,因为我正在使用AccountManager.getAuthToken()在线程中恢复令牌,因此在恢复此令牌之前会创建片段.因此我无法从我的服务器请求数据.
这让我觉得我的应用程序结构可能不那么好.所以我在想,"如果我这样喜欢怎么办?" :
这样我就可以认为MainActivity会让令牌通过,但我不确定它在UX方面是否理想.(在访问内容之前必须等待令牌).因为我真的被卡住了,所以我现在对所有的建议持开放态度.
谢谢 !
更新1:
它更像是一个登录/注册应用程序逻辑,而不是处理AccountManager.我已经成功地使它们工作但我真的很挣扎于"最佳实践"应用程序逻辑结构,所以我不会因为它而遇到很多其他问题(因为我没有时间).我只需要一个图表或其他东西来向我展示一个"最佳实践"示例,以使我的应用程序按照我上面解释的方式工作.我也遇到了一个问题,因为当我启动MainActivity时它会检查一个帐户,如果没有它会启动LoginActivity但是如果我按回来,我可以看到MainActivity(未填充).
您正在使用的是更多的常规做法:

这种结构是完全可以接受的,并且是依赖于服务器的应用程序的正常流程。我更喜欢这种模式,其中日志记录只是其中一部分内容不需要登录的选项。每当触发需要登录的操作时,就会向用户显示登录信息。但是,您的模型应该可以正常工作。
我知道你的问题是
I also ran into a problem because when I start the MainActivity it checks for an account and if not it launches LoginActivity but if I press back, i can see MainActivity (unfilled).
可以使用不可见的调度活动来解决此问题,该活动可以基于当前用户的状态启动MainActivity或LoginActivity。如图所示,finish()在您做出决定后只是调度活动。您的LoginActivity负责重新启动DispatchActivity,它将在下一步重新出现。通常,不要覆盖LoginActivity的onBackPressed来启动Dispatch,只有在成功登录后才启动Dispatch。
但是,如果您决定即使用户未登录也要在“活动”中显示一些“内容”,则可以onActivityResult在登录请求后使用刷新MainActivity的“内容”。
The problem is that my fragments can't get this token because, as i'm recovering the token in a thread using AccountManager.getAuthToken(), the fragments are created before this token is recovered.
这个问题很正常。如果在处理登录请求时已经创建了活动/片段,则您必须能够告知这些活动/片段。基本上,如果您的片段不显示“未经身份验证”的内容,那么您就不会遇到这个问题,因为在登录之前,甚至都不应该创建这些片段。
但是,同样,如果您决定甚至在用户未登录时也要在“活动/片段”中显示某些内容,则必须通知这些正在运行的组件有关状态更改的信息。一种方法是在您的活动中实现onResume,以检查用户是否已登录并进行了适当的更改。另一种方法是使用本地广播来通知正在运行的活动/片段状态已更改:
BroadcastReceiver mReciever = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//do whatever you want //check state
}
};
public void onCreate(Bundle state) {
//bla bla
//bla bla
LocalBroadcastManager.getInstance(mContext).registerReceiver(mReciever, new IntentFilter("your_package_name.LOGIN_STATE_CHANGED"));
}
Run Code Online (Sandbox Code Playgroud)
每当状态改变时,发送广播:
Intent intent = new Intent("your_package_name.LOGIN_STATE_CHANGED");
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)当然,这可能会因情况而异。例如,如果您在Google Play上选中Touch App,您会注意到我创建了一个分派屏幕,无论用户的登录状态如何,该屏幕都可见,然后询问用户是否输入需要登录的活动。在这种情况下,任何需要登录的活动都应相应地实现其onActivityResult并在用户登录时更新ui或在用户未登录时完成。另一方面,Google Play上的psst应用程序会使用启动画面来根据用户状态决定是进入登录画面还是进入主画面。