I have some Activites that are started from my main Activity. When I go to one of these Activities, press home, kill the process, return to the app (where it resumes on Activity I left from), and then press back, it just closes my app instead of going back to my main Activity. I expect the back stack to be preserved. Does anyone know why this is happening?
I'm doing 3 things that might be related:
(1) My main Activity has launch mode singleTask
I tried removing this, but it didn't solve the problem. For example:
<activity
android:name=".activities.ActivityMain"
android:launchMode="singleTop"
android:screenOrientation="portrait">
</activity>
(2) I'm overriding onBackPressed() in the secondary Activity, but calling super.onBackPressed() when I do indeed want to go back. I also tried not doing this, but it also didn't help. For example:
#Override
public void onBackPressed()
{
Logger.d("ENTER");
ViewUtils.closeKeyboard(this);
//kv If it's a valid location, but hasn't changed, then just finish up
if (((FragmentLocation) getFragment()).isValidSpecifiedLocation()
&& !((FragmentLocation) getFragment()).sendUserSpecifiedLocation())
{
finish();
overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
}
}
(3) I'm setting the parent Activity in the manifest to my main Activity (I've also tried removing this, but it doesn't help):
<activity
android:name=".activities.ActivityLocation"
android:screenOrientation="portrait"
android:parentActivityName=".activities.ActivityMain">
</activity>
Any ideas?
UPDATE:
I tried recreating a very simple example with these conditions, but couldn't reproduce. I'm not sure what's causing this issue at this point.
Related
I have two activities.
In the first one I have a button like this :
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(this, Activity2.class));
}
});
Then in my SecondActivity, I have a EditText.
But when I tap on the EditText, the keyboard is well showing but I can see the view of the FirstActivity during the keyboard slide animation. Is that normal ? I don't think so .. So I'm trying to understand what I have done wrong ..
Manifest.xml
<activity
android:name=".activities.Activity1"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent.NoTitleBar"/>
<activity
android:name=".activities.Activity2"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="adjustResize"/>
Thanks in advance !
If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.
onDestroy() is the final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
And for your question you have a android:theme="#android:style/Theme.Translucent.NoTitleBar" which display transparent activity that is the reason to display your previous activity behind because the background is transparent and you have not finished the previous activity, so you see it. If you finish it i doubt you might see the mobile screen as well if you don't have any back states
I don't know your requirement depending on that you can,
Change the transparent Theme
Remove previous activity from back state
Go with 1 & 2
I encountered strange problem, lets say I have two activities A and B, app starts with Activity A, I proceed to activity B press Android Home Button, return to app which brings me back to Activity B. Then I press Back button (either hardware on in toolbar) and this closes app, but it should return me to Activity A. Activity B has no override of onBackPressed and has Activity A stated as PARENT_ACTIVITY in manifest. I'm starting it with Intent with no flags. Any idea why this happens ? Thanks
The behaviour of back buttons depends on system version. There is support for providing back navigation in older Android versions, described here:
https://developer.android.com/training/implementing-navigation/ancestral.html
<application ... >
...
<!-- The main/home activity (it has no parent activity) -->
<activity
android:name="com.example.myfirstapp.MainActivity" ...>
...
</activity>
<!-- A child of the main activity -->
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
The best and most convenient way to debug back stack issues is to enable 'Don't keep activities' option in developer options.
That's my best guess. Good luck!
In order to run a new activity without destroying the old one, you have to add the flag FLAG_ACTIVITY_NEW_TASK to the intent that will run the activity:
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
as when setting this flag:
this activity will become the start of a new task on this history
stack. A task (from the activity that started it to the next task
activity) defines an atomic group of activities that the user can move
to. Tasks can be moved to the foreground and background; all of the
activities inside of a particular task always remain in the same order.
so the activity which started it will remain in the stack, and hence you can call it again, and hence it also can be called automatically again when pressing BACK_BUTTON even if you pressed the HOME_BUTTON earlier.
and you have to combine #gduh answer with mine, as for sure you must make sure that you are not calling finish(); in ActivityA while calling the ActivityB.
thanks for help, problem was caused by this flag for activity in manifest android:launchMode=singleinstance (it's not originally my project so I missed that, I just hope I didn't screw something else up by removing it)
In your activity A when you call your activity B, maybe you have the following command :
finish();
If yes, you should remove this line. Then when you press back key from your activity B you should return A.
If not, maybe try to share your code.
So here is my activity.
<activity
android:name=".MainActivity_Hard"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="#string/title_activity_main_activity__hard"
android:noHistory="true"
android:screenOrientation="portrait" >
</activity>
I marked it as android:noHistory="true" because I did not want the screen to be added to the activity stack.
But however when I lock the screen and unlock it. The activity disappears and the previous screen appears. This should not happen. Could anyone tell me why.
Note: It happens in ICS (Samsung Galaxy Note), but not with previous devices (Gingerbread,etc.)
Setting the noHistory attribute in your activity means that as soon as the user navigates away from that activity--bringing up the lock screen included--its finish() function is called automatically, thus destroying it and going back to the previous activity that spawned it.
This is typically used for splash-screen-type activities which, for example, acts only as a launcher and you don't want the user to be able to go back to the splash screen from the child.
If this is not your intention, then you should consider removing the noHistory attribute and maybe managing the activity lifecycle yourself. (For example, if you don't want your activity to be in the stack, then just call finish() just after it starts another activity.)
android:noHistory
Whether or not the activity should be removed from
the activity stack and finished (its finish() method called) when the
user navigates away from it and it's no longer visible on screen —
"true" if it should be finished, and "false" if not. The default value
is "false". A value of "true" means that the activity will not leave a
historical trace. It will not remain in the activity stack for the
task, so the user will not be able to return to it.
I don't know why. But if you don't want to add this activity to current stack. You can set android:launchMode="singleTask". When start this activity it will be added to it own stack.
You can see more here enter link description here
Hope it help :)
In AndroidManifest.xml put this permission tag above application tag.
<uses-permission android:name="android.permission.WAKE_LOCK" />
I don't want the user to be able to go back to the splashscreen of my app. One solution seems to be to check if the activity below the current one is an instance of the splashscreen, and in that case exit the app, as shown in the code below. However, I don't know how to check what's the previous activity in the stack. Anybody can help? Is there any other way to disable 'go back' to a given activity?
#Override
public void onBackPressed() {
if(<previous activity in stack is an instance of splashscreen>){
Intent exit_intent=new Intent(CurrentActivity.this, SplashScreen.class);
exit_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
exit_intent.putExtra("EXIT", true);
context.startActivity(exit_intent);
}
}
Call finish() in your Splash Screen activity right after starting the next activity.
Another approach is to add this attribute to your activity in AndroidManifest.xml: android:noHistory="true"
Example:
<activity android:name=".SplashActivity" android:noHistory="true"/>
This attribute instructs Android to remove SplashActivity from the history stack once its navigated away from.
Just call context.finish() after context.startActivity()
try the following when calling the next Activity from your Splashscreen:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
<activity android:name=".SplashActivity" android:noHistory="true"/>
From the documentation:
Whether or not the activity should be removed from the activity stack
and finished (its finish() method called) when the user navigates away
from it and it's no longer visible on screen — "true" if it should be
finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical
trace. It will not remain in the activity stack for the task, so the
user will not be able to return to it. In this case,
onActivityResult() is never called if you start another activity for a
result from this activity.
This attribute was introduced in API Level 3.
I am trying to solve an issue sort of similar to what was done here (link text)
Except in my case where Activity A, started Activity B, started Activity C, when the user resumes the app after pressing the home button - I want C, the last Activity, to be displayed. Instead what is happening is I am back to A.
Also on a side note I have discovered that even when I exit the application, if I hold down the Home button, my app is still listed as an active app even though in the LogCat I can see that it exited OK.
Also, in case it matters, I did recently add android:launchMode ="singleTask" in order to make some notification logic work correctly. I was seeing the Home button behavior before that though.
I really appreciate any ideas you might have.
[edit - adding some code snippets]
<activity
android:name =".connection.ActivityA"
android:label ="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:theme ="#android:style/Theme.NoTitleBar"
android:launchMode ="singleTask"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name ="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name =".screens.AvtivityB"
android:label ="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:theme ="#android:style/Theme.NoTitleBar"
android:launchMode ="singleTask"
android:screenOrientation="portrait" >
</activity>
<activity android:name =".screens.ActivityC"
android:label ="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:theme ="#android:style/Theme.NoTitleBar"
android:screenOrientation="portrait" >
</activity>
Then here is how I kick off each Activity:
In Activity A:
private void startActivityB()
{
Intent activityBIntent = new Intent(this, ActivityB.class);
this.startActivityForResult(activityBIntent , ACTIVITYB_TAG);
}
Activity B actually has several Activities that it chooses from (it has a list of Intents) to display based on input it receives but launches them all the same way as Activty A launched B. Once the first Activity is displayed the user swipe the screen to navigate to the left or right screen. When the user swipes left or right, the current activity puts info in its return Intent that Activity B uses to display the next Activity. Also since logic outside of the user's control could prompt a change in the screen displayed, each Activty calls finish on itself in onStop to avoid back-button issues.
When you long press home it is showing a list of recently active applications, not applications that are currently running. So you should still see your app in the list, even if it is closed.
As the docs note:
The other modes — singleTask and
singleInstance — are not appropriate
for most applications, since they
result in an interaction model that is
likely to be unfamiliar to users and
is very different from most other
applications.
I'd imagine that your using singleTask is affecting the history stack, and thus preventing Activity C from being remembered. If you remove that from Activity C, does it resolve the problem?
Otherwise, I'd look at what you are doing in onPause/onDestroy etc for Activity C. Are you doing something that would cause it to finish or close?
Do you get this behavior only when running from Eclipse?
Check your "Run Configurations". There is a "Launch Action" that can be set to "Do Nothing".
Matt
I'm not sure this is what it happening to you, but the answer below solved my problem and I wanted the same behavior as you - that is, getting to the same activity when re-opening after home has been pushed (though in my case, I did actually want the first activity, just not a new one):
Save activity state in android when home button pressed
Now I realize you want to keep the activity stack intact and not go to the first activity like me. But if it is the same problem, then it is not from the fact that the activity stack is torn down, but because a new one (with the opening activity) is added when re-opening after home has been pressed on first install. I hope this is fairly legible, even though I (clearly) found it difficult to explain.
Edit: This is better described here and here.