I have three activities, each with different layouts..
All three layouts have one thing in common (three ImageButtons) to switch between the activities. In the onClick of the Imagebuttons, I use an intent to open the activity.
Here is the problem:
The ActivityA plays a song, now when I click play, the song starts, if I decide to switch to activityB, it opens. From Activity B, if I wanted to go back to ActivityA by clicking the corresponding ImageButton, it creates a new instance of activityA with its default layout (No song is played) but I can still hear the song.
Meaning that a new instance of ActivityA was created, I dont want it to be like this, I want it that when I click the corresponding ImageButton, it goes to the previous activity in the same state as I left it before I switched to ActivityB.
I thought this might solve the problem, but I dont think it would considering I have three Activities (might have used it if it was just two activities)
public void onClick(View view) {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
I would suggest using a tab navigation or navigation spinner instead of creating new activities.
But if you really want to use separate activities, you could try putting this in the activity tags of your manifest file:
android:launchMode="singleTop"
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
I got it to work, using
android:launchMode="singleTask"
in the android manifest.
android:launchMode="singleTop"
didnt work as Mark Bukeima suggested above, but he did push me in the right direction to know I was to use the android:launchMode="singleTask".
It might be cause you start your activity using starActivity() instead of startActivityForResult() to switch from ActivityA to ActivityB.
Here's how you should do it :
/* In ActivityA */
public void onClick(View view) {
Intent intentToB = new Intent(this, ActivityB.class);
startActivityForResult(intentToB, 0); // Will start B whithout killing A
}
Related
Suppose I have an Activity named ActivityA and another Activity named ActivityB. In each one I have a button that opens another Activity when it is clicked. I want to do following work when button is clicked:
check if there is an existing type of the target Activity in the activity back-stack or not, if there is, bring that Activity to the top and if not create new Intent and then go to that Activity.
How can I implement this?
Thanks.
Simple.
Intent intent = new Intent(this, TargetActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
This does exactly what you want. If there is already an instance of TargetActivity in the task stack, that instance will be rearranged and brought to the top (front) of the stack. If there is no existing instance of TargetActivity, Android will create a new instance and put that on the top of the stack.
I have four activity for my application, Main Activity -> second Activity-> Third Activity -> Fourth Activity. Each Activity contains the onBackPressed method implemented. Every time when the onBackPressed method called, it sends an intent to the previous activity. For Example, in Fourth Activity onBackPressed method, it contains an intent to go to the previous Activity, which is the Third Activity. This works fine upto the MainActivity. When I press on the back button on the MainActivity it must exit the application. However, it just starts the next activity, which is the second Activity. What causes this bug???
Here is some relevant code.
From the fourth activity:
#Override
public void onBackPressed() {
Intent intent = new Intent(this,third.class);
intent.putExtra("id",FinalID);
intent.putExtra("Image Item", categoryItem);
startActivity(intent);
}
From the third activity:
#Override
public void onBackPressed() {
Intent intent2 = new Intent(this, second.class);
intent2.putExtra("Image Item", categoryItem);
Toast.makeText(this, "theFinalActivity=" + categoryItem.getId(), Toast.LENGTH_SHORT).show();
startActivity(intent2);
}
The second activity looks like the following.
#Override
public void onBackPressed() {
next = false;
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
And finally the code in the MainActivity:
#Override
public void onBackPressed() {
System.exit(0);
}
Android System internally handles the backstack for the activities. You don't need to explicitly handle going back if you're not supposed to override the default behavior. In your case, On pressing back, you're not popping the current activity, instead you're pushing a new one into the backstack. This will result in ambiguous behavior of your back button.
First, the onBackPressed function is not required to be implemented only if you are caring about taking care of the activity stack (i.e. finishing up your third activity will bring back the second and finishing the second activity will bring up the first one and so on). The activity stack is already taking care of it.
Secondly, if you want to pass the data to a caller activity from the activity that you have opened from the caller, this is not the ideal way to do so. I would like to recommend you to read this documentation where it explains how to pass such intents in a graceful manner using the life-cycle functions provided by Android.
Just to give you a heads up, here are three steps for you to pass the data between activities in a backward direction.
You need to start the second activity from the first activity using startActivityForResult instead of startActivity with a request code passed along with it (so that you can differentiate between different request codes from other activity if there is any).
Then in your second activity, if you need to pass something to your caller activity (i.e. the first activity), you need to use setResult to pass the desired data back to the caller and finish() the second activity.
In the first activity, you need to implement onActivityResult function to get the data back from the second activity.
Here is a nice example of the overall implementation where you can take a look too.
I know that you are expecting that the system.exit(0) should kill the application whatever the situation is. However, in Android, it does not work in the way that you have expected I think. I am quoting from this answer on StackOverflow to explain how the system.exit(0) works.
System.exit(0) - Restarts the app with one fewer activity on the
stack. So, if you called ActivityB from ActivityA, and System.exit(0)
is called in ActivityB, then the application will be killed and
started immediately with only one activity ActivityA.
I hope that helps!
I have multiple activities. In my main activity, I have my listview within an arraylist. When I go to the second activity and press the back button on the second activity to return my main activity, my arraylist size becomes zero therefore I am losing my listview entries.
Is there any way to keep my arraylist when I go back to the previous activity?
Note: On the second activity, my code is as follows:
public void onBackPressed(){
Intent intent = new Intent(SecondActivity.this, MainActivity.class);
startActivityForResult(intent, 0);
}
Given the comments you have left I'd suggest you create a management class. This class will store all of your default values and you can update it as needed from other classes.
You don't need to override onBackPressed() because the default behavior has your list retained. By overriding onBackPressed(), you are recreating MainActivity which consumes more resources as you are having two MainActivity opened (the initial in the background and the latter activated by onBackPressed ())
I have a problem with a nullpointer exception when I return to a previous activity by using the UP button in the action bar.
I'll try to explain my flow:
ActivityA.java:
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra(KEY, value);
startActivity(intent);
ActivityB.java:
Obj o = getIntent().getSerializableExtra(ActivityA.KEY);
o.doStuff();
Intent intent = new Intent(this, ActivityC.class);
startActivity(intent);
ActivityC.java:
// Do some stuff, then finish
finish();
Now all this works fine when I press a button on Activity C that triggers the finish()part.
The problem occurs when instead of pressing that button I press the UP button on the action bar to go back to Activity B. Then I get a nullpointer because he tries to recreate Activity B, and fails on the line o.doStuff();
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{ActivityB}:
java.lang.NullPointerException
How can I solve this? How can I prevent the Activity B from needlessly recreating? Please keep in mind that I'm doing this Android stuff since Tuesday ..
I know that this might not be what you want but this scenario is not uncommon and what I find myself doing at times is if (o == null) in ActivityB I do finish(). This leads the user back to ActivityA. If ActivityA is not in the backstack, then the app finishes. This is what happens with Instagram at times. It's not perfect but it's not that annoying, I think.
If it's a must to go back to B, you could actually just transfer your Object in your intent to C. And before finish() in C, you could fire a new StartActivity(B.class) with Object as extras to B.
You should look at the Android Activity lifecycle. The problem is that starting a new Activity can destroy an old one in memory, and if you don't return to an Activity for a while its memory will be reclaimed. You need to take a look at onPause() and onResume() to see what you can do to save state.
https://developer.android.com/training/basics/activity-lifecycle/starting.html
It's not that Android "needlessly" recreates the Activity, it does it all the time. If you change orientation, your Activity is destroyed and recreated. If you start a bunch of apps and Android needs the memory currently held by an inactive app, it'll be destroyed and will be recreated when you next launch it.
As an aside, if you're not going to use the lifecycle callbacks onPause() and onResume(), you should at least check to see if your object is null and recreate it in onCreate().
I have 3 Acivity based application, It's work flow like this MainActivity ListView and DetailView. when onResume event trigger , need to call MainActivity. without going to other two activity.
Is there any way to call MainActivity when onResume event trigger?
Thank You
You can set the android:clearTaskOnLaunch="true" attribute for you MainActivity in the AndroidManifest.xml file. See here to find why and more details. I think this is the most convenient way to meet your demand.
Edit:
I just tested and found this only works when you exit the app and launch the app from the app drawer(NOT long press on HOME and select the app).
If you want to always bring the root activity to the front, no matter when you re-launch the app or from the recent screen. You can declare "android:launchMode="singleTask" for the root activity, here, the MainActivity.
The best solution I can think of is to start the activity again in the onResume of all your other activities:
#Override
public void onResume() {
Intent myIntent = new Intent(this, MainActivity.class);
startActivity(myIntent);
}
The user will still be able to hit the back button and go back to the previous activity, however.
If you want to quit your List/Details views when the user closes your app, have them finish() themselves in their onPause which is called when your Activity is closed.
The only caveat here is that calling finish() will move it one Activity back in the ActivityStack so if your MainActivity isn't the one launching the List/Details views, it will not go back to the MainActivity. In this case, you could specify in the AndroidManifest.xml
<activity android:name="sample.activity.MyActivity" android:noHistory="true" />
to prevent the List/Details activities from ever being put into the history.