If I call an activity Activity_B and 1 of it's instances is already present in the backstack, I want to go back to that Instance, removing all the activities in between, and recreate that instance(to refresh content).
I tried:
Intent intent = new Intent(Activity_A.this, Activity_B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
and in Activity_B:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("Activity_B", "onNewIntent");
//Thought of refreshing the content here.
}
I never found anything which will do all the above actions.
The best I could found was FLAG_ACTIVITY_SINGLE_TOP which will not recreate the Activty, instead it will call onNewIntent() where I can refresh the content.
But every time a new instance of the Activity_B is called.
What am I missing?
Thank You
Try using FLAG_ACTIVITY_REORDER_TO_FRONT instead. It will bring the previously running instance of your activity to the front if it exists.
Once the activity comes to the foreground, it's onResume() method will be called as usual where you can refresh your UI.
Related
Suppose I have two activities A and B activity A which contains a button I want to start Activity B when I press Button without intent.
According the Oficial Documentation:
An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.
An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.
So you have to use it to open activities with no exceptions or workarounds, if you do that, you are ignoring the entire system architecture.
There is no way to start an activity from anotherone without an intent.
If the reason of not using Intent that you don't want the the user to re-enter the previous activity
You can use finish() to finish that activity intent after you done work with
if(currentUser == null){
startActivity(new Intent(MainActivity.this,StartActivity.class));
finish();
}
So user will be unable to back again
If you want to do some code while the activity is finishing
You can use onDestroy() override method, Sometimes it can also be called if the activity is being killed by the android itself so you can add
isFinishing() function
Inside onDestroy() method which checks whether the application is closing by the call finish() returning true or otherwise by anything else returning false then you can easily specify your code for each situation.
#Override
protected void onDestroy() {
super.onDestroy();
if(isFinishing()){
// Activity is being destroyed by the function `finish()`
// What to do...
}else{
// Activity is being destroyed anonymously without `finish()`
// What to do...
}
}
Put your activity inside a Fragment and start the fragment fromo the button.
These are the possible ways to start any Activity
1st
startActivity(new Intent(Activity_A.this, Activity_B.class));
2nd
Intent intent = new Intent(Activity_A.this, Activity_B.class);
startActivity(intent);
3rd
Intent intent = new Intent(Activity_A.this, Activity_B.class);
startActivityForResult(intent,code);
I have a problem concerning startActivity(intent) and onStop. The Android API suggests to save data in onStop, which is what I am doing here:
public void onStop(){
super.onStop();
if(tosave)
{
Editor editor = sp.edit();
editor.putInt(getString(R.string.index_of_text_color), text_color_index);
editor.putInt(getString(R.string.index_of_background_color), background_color_index);
editor.commit();
}
}
However, I would like to start the next activity once it is saved- so I need to use an intent and startActivity(intent).
public void click(View v){
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
My question is, does startActivity(intent) with the two flags call the onStop() method as it is finishing the application, or do I need to call finish()? Is it allowed for me to call finish() after I start a new activity? Or, is it because the new activity will be at the top, Android automatically calls onStop as it is in the background now?
There are so many questions about how startActivity(intent) works with the app cycle that I do not understand. It will be helpful if someone points me to a link.
Thank you!
EDIT: the intent is not in onStop. It is in another method which corresponds to a button. As soon as the button is clicked, I will need to save the data-- go to onstop-- and then go to the next activity. How can I do that?
You should save state in onPause(), not onStop(), because under certain conditions onStop() will never be called. You are guaranteed that onPause() will be called.
onPause() will always be called on your activity when another activity is shown in front of it.
That should solve your problem.
Inside a broadcast receiver I want to start my app (Activity) and pass in some data.
My problem is that the extras don't seem to carry over into the activity. I am trying to get the data inside the onNewIntent(Intent i) function.
Any ideas?
Here is my current attempt in the BroadcastReceiver:
Intent intSlider = new Intent();
intSlider.setClass(UAirship.shared().getApplicationContext(), SliderMenuActivity.class);
intSlider.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intSlider.putExtra("action", ScreensEnum.Object);
intSlider.putExtra("objectId", objectId);
intSlider.putExtra("objectCode", objectCode);
intSlider.putExtra("userId", userId);
UAirship.shared().getApplicationContext().startActivity(intSlider);
EDIT - Added code used in onNewIntent() and onCreate()
The following code works great in onCreate() when the app isn't currently running. For when the app is already running the same code doesn't work (i.e. no extras) from the onNewIntent() function.
Intent intent = getIntent();
if(intent.hasExtra("objectId")) {
loadDetail(intent.getStringExtra("objectId"), "2w232");
}
The problem is getIntent() method. It always returns the intent that started the activity, not the most recent one. You should use intent that was passed to onNewIntent method as an argument.
We stumbled upon this problem once, when we were trying to launch/call onNewIntent on an Activity in response to a local notification tap. The extras that we put on our Intent were disappearing at the time onNewIntent received it.
I don't remember this being documented anywhere back then, but the "problem" was that we weren't setting the action field on the Intents that we prepared. Turns out if the Intent received by your Activity doesn't have an action set using setAction, the system still delivers the Intent to its destination, but doesn't transmit the extras you have set while creating the Intent.
TL;DR:
If you encounter this problem with an Intent with no action, calling setAction to set an arbitrary action value before sending the Intent might fix it.
Extract from the docs
This is called for activities that set launchMode to "singleTop" in
their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag
when calling startActivity(Intent). In either case, when the activity
is re-launched while at the top of the activity stack instead of a new
instance of the activity being started, onNewIntent() will be called
on the existing instance with the Intent that was used to re-launch
it.
An activity will always be paused before receiving a new intent, so
you can count on onResume() being called after this method.
Note that getIntent() still returns the original Intent. You can use
setIntent(Intent) to update it to this new Intent.
I think the last paragraph explains your problem.
You have to set the flag FLAG_ACTIVITY_SINGLE_TOP or set launchMode singleTop in the manifest file.
Of course when onNewIntent is called you do not use getIntent but the Intent received as argument.
onNewIntent will be called when the activity instance already exists. For example, if last time you pressed the Home Screen button.
I wrote a solution that worked for me here: Intent with old extra in onCreate() for singleTask Activity
You can store the last received intent in a member variable (mLastIntent).
Then you can use this member in your onResume() method to query for your extra data.
private Intent mLastIntent;
#Override
protected void onNewIntent(Intent intent) {
mLastIntent = intent;
};
If I call startActivityForResult and the activity that starts is also calling startActivityForResult on another activity,
is it possible that the first activity will be stopped ?
Is there a way to prevent it from happen?
What context should I pass each intent I create?
some code to figure the process
intent = new Intent(MainActivity.this, SettingsActivity.class);
startActivityForResult(intent, AbstractSettingsActivity.SETTINGS_ACTIVITY_REQUEST_CODE);
// this is inside the Settings activity
Intent intent = new Intent(getBaseContext(), SettingsTabsActivity.class);
startActivityForResult(intent, CUSTOMIZE_TAB_REQUEST_CODE);
// at this point i got ondstroy on main activity - main is not the root
In any case (either its startActivity or startActivityForResult), when you start a new activity, your current Activity will go into stopped state by raising its onStop method. Its the way Android's Activity life-cycle is designed. It has nothing to do with a type of context.
However, if you don't want to occur onStop, then perhaps you may try emulating the expected view(s) through Dialogs which will cause your Activity to reach up till its onPause state.
I have an activity called HomeActivity that has a SurfaceView and shows a camera preview picture. This activity is quiet heavy and feels slow if you are starting/restarting it.
So I made some investigations and found out, that somehow always the onCreate method is being called. In my opinion this should not happen if the Activity has already been started?
The documentation says :
Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.
Always followed by onStart().
Here is the method, that handles going back:
protected void gotoHome() {
final Intent intent = new Intent(SomeOtherActivity.this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
Edit:
Here is how I am leaving HomeActivity ... nothing special:
final Intent i = new Intent(HomeActivity.this, SomeOtherActivity.class);
startActivity(i);
Yes, when you want to return to the HomeActivity, you need to use these flags:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
Here's the relevant section from the documentation on Intent.FLAG_ACTIVITY_CLEAR_TOP:
The currently running instance of activity B in the above example will
either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new
intent. If it has declared its launch mode to be "multiple" (the
default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same
intent, then it will be finished and re-created; for all other launch
modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be
delivered to the current instance's onNewIntent().