I have two activities, first one is LoginActivity, the second one is MainActivity. When an error occurs on MainActivity I get force close dialog which is ok, but why does my app goes to previous activity and runs some code on it and then I get another force close?
Shouldn't app close immediately when error occurs on particular activity, instead of after crashing on MainActivity I see in log that it executes some code on LoginActivity as well and if not not properly handled, it crashes there too so whenever I get an error on MainActivity it triggers one more force close dialog on LoginActivity?
What do you expect the user experience to be? What if they press the back key?
When an Activity crashes the app opens the last Activity that was running as it's at the top of the activity stack. So what you're experiencing is expected behaviour. But you weren't expecting it so it seems you may have structured the flow of your app incorrectly.
When the user starts your app they should be presented with the main activity, when they try to log in they should be presented with the login activity, once login is complete the login activity should be finished so it does not remain in the activity stack.
If you do not finish the login activity and instead start the main activity then the user will be able to press the back key to return to the login activity which is not ideal, as they are already logged in.
Related
I am working on this Android Studio project, and after I'm making some checks in the Login activity, I want to be redirected to the MainActivity and finish the Login activity. However, after I login and I am being redirected to the MainActivity, if I press the back button, it will redirect me back to the Login Activity(the first time the login activity not being closed/finished). If I try to repeat the process and press back, this time works as desired, that is, it closes the app(the Login activity is closed/finished)
I checked my code a few times now, and I am not starting the same activity twice, so does anybody know why this happens and how to fix it?
Try to use finishAffinity() which closes the current activity and clears the stack. Then you will be left with MainActivity only.
More information: https://developer.android.com/reference/android/app/Activity#finishAffinity()
From a Service, I launch an Activity in my application. This is not the main application activity, just some random other activity.
After the user has interacted with this Activity, I want to close it and return the user to where he was. So say for example he was in Facebook. My Activity gets launched. When he is done interacting with it, I want to return the user to Facebook. However, when I call finish() or backPressed() or anything like that, the Main (launcher) Activity of my application is started. I don't understand why.
I have a typical Android app where the user has to log in before displaying the main Activity of the application. However, if we've already got a cached username / password, I want to skip the login page.
I could, in my Login onCreate, detect if I've got a user/pass and push a new Activity, but I'm worried that this will make my app startup slower (since I have to load an activity then immediately throw it away), and it also perhaps breaks the back button (i.e. you can hit back and end up back at the login screen).
Is there any way to avoid this and only load the full Login Activity if there is no cached password?
You can make a separate helper activity which launches either your login activity or your main activity. In its onCreate, you'd use startActivity and immediately call finish to remove the helper activity from the back stack.
Intent intent;
if ( /* already logged in */ ) {
intent = new Intent(this, MainActivity.class);
} else {
intent = new Intent(this, LoginActivity.class);
}
startActivity(intent);
finish();
Then, LoginActivity should re-launch MainActivity as normal. This way, the user will never be able to navigate back to the helper activity as it does not appear in the back stack. Do note however that the user can still login, go to the MainActivity, pause that activity, remove his account (through the Android settings) and resume the activity (from the recent apps). If you want to prevent this, you're probably better off placing the login redirect in MainActivity instead (perhaps even in onResume).
You could create a Splash Activity.
On the AndroidManifest.xml's Splash Activity tag, add the android:noHistory="true".
On the Splash Activity, check whatever you need (maybe with an AsyncTask if it may take a long time, to avoid freezing the Activity) and, depending on the result, you start the Login Activity or any other Activity.
Another approach is to transform login screen from Activity to Dialog. That should be easy. And then make your main activity check if there is cached username/password or not. In the second case show LoginDialog to user.
I also have a typical Android app with the same requirement, and I solve it as follows.
First I configure the initial launch activity to be MainActivity, and then inside onCreate(), check if the user has saved credentials (this is all done through AccountManager and authenticator service).
If the check fails and user needs to authenticate, then I start the LoginActivity. If logging in fails or the user presses back, the MainActivity calls finish() on itself to close the whole app. Otherwise, after logging in, the MainActivity is resumed and is presented to the user properly.
The advantage of doing it in this order is that (in my case anyway) the user is more likely to be logged in than out, and so this will avoid any start/stopping of unneeded activities as you say.
A second advantage is that, if the MainActivity (or another activity) is resumed at a later time and the user's session has expired, you can simply start the LoginActivity again to reauthenticate them.
Hope that all makes sense :)
The home screen of my app needs to have different behavior when the app is being launched from outside the app versus when a back navigation occurs. For example, imagine an Android Twitter client which on launch tries to get your updated feed but when you click on an item to hit its detail page and hit back, the screen doesn't reload new feeds but is instead where you left from.
So far I've tried looking at the calling package property but this hasn't helped since it seems to be null both when app is launched by the user for the first time or when I hit back from a detail page.
When user launches it first time, onCreate() then onresume() will be called for sure. When navigating back and getting your activity from backstack, just onResume will be called.
Also if you activity has singleTop set, then you can look into onNewIntent() which will be called when you navigate back to your activity from other screens.
So, the solution I can suggest you is to set singleTop for your activity. Then while navigating back using onNewIntent(). For 1st time launch onCreate() will be called.
Sorry if I could not understand your question well..
I am programming an Android application and have a curious issue.
My application has a LoginActivity that defines the filter for launch events.
As soon as login is complete, it starts the "Home" activity using startActivity(new Intent(LoginActivity.this, HomeActivity.class)) and stops the LoginActivity using finish().
The HomeActivity is a simple dashboard with notifications, overriding onCreate and onStart. Also it updates the some content icons using an AsyncThread.
The problem is this: If I hit the Home-Button to exit my app and then use the "recent" menu (holdpress the Android-Home Button) to reopen it, the back-key is 'broken' in my app: Pressing it will not finish the HomeActivity, but instead loop back to the same activity:
Meaning ... HomeActivity <- HomeActivity <- HomeActivity <- HomeActivity ...
I have not used any hacks to override the backstack or back key behaviour.
Anyone got a clue what the cause of this may be?
TIA, Patrick
Maybe your login activity detects that login is complete and sends you immediately back to your home activity. That should be visible from the log (ActivityManager, START intent ...)
In that case it may be a good idea to play with the backstack