More of a general practice is what you're using:
This structure is completely acceptable and is a normal flow of Server-Dependent apps. I prefer the model where logging is is just an option with some content that does not require logging in. Whenever an action that requires login is triggered, the user is shown the login. However, your model should work fine.
I see that your problems are
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).
This issue can be solved with an invisible Dispatch Activity that launches the MainActivity or the LoginActivity based on the status of the current user. As in the diagram, just
finish()
the Dispatch Activity after your decision. Your LoginActivity is responsible of relaunching the DispatchActivity which will redecide on the next step. Generally, do not override the onBackPressed of the LoginActivity to launch the Dispatch, just launch the Dispatch in case of successful login.However, if you've decided to show some Content in your Activity even if the user is not logged in, you can use the
onActivityResult
to refresh the Content of the MainActivity after a login request.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.
This problem is normal. If your activities/fragments are already created when you are processing a login request, you must be able to inform these. Basically, if your fragments do not show "unauthenticated" content, then you should not face this problem because you should not even create these fragments until you are logged in.
However, again, if you've decided to show some content in your Activities/Fragments even when the user is not logged in, you have to inform these running components about the status change. One way to do that is to implement an onResume in your activities that checks if the user is logged in and does the suitable changes. Another way is to use a Local broadcast to inform running activities/fragments that the state has changed:
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")); }
Whenever the state changes, send a broadcast:
Intent intent = new Intent("your_package_name.LOGIN_STATE_CHANGED"); LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
Of course, this can turn out to be case-specific. For example, if you check the Touch App on Google Play, you will notice that I've created a dispatch screen that is visible regardless of the user's login state and then asked the user to login if he enters an Activity that requires login. In this case, any activity that requires login should implement its onActivityResult accordingly and update the ui if the user logged in or finish if the user didn't. On the other hand, the psst app on Google Play uses a splash screen to decide whether to go to the Login Screen or the Main Screen depending on the user's state.