If i use the code below will this restore text that has been input into EditTextfields and selected spinner items?
#Override
protected void onPause(){
super.onPause();
}
#Override
protected void onResume(){
super.onResume();
}
or do I have to tell it to save the current values and then restore then when activity is resumed? when I am using the emulator if I don't have these methods in and I go to say home then run my app again it always loads back to the previous state, so my questions is does this actually do antyhing?
Nope, this actually only called the super class onPause() and onResume() without doing anything else. The value in your editbox stay there because even if the app is paused, is still there on the activity stack waiting.
However Android can kill your paused activity and your data will be lost. So you have to save them onPause and restore them on the onResume to avoid this.
No, this code does not do anything. You're overriding these methods, but giving them an implementation of just calling the parent implementation. This is the same as not overriding them in the first place.
It's not absolutely necessary to save/restore state for when you pause/resume. The only reason why you would need to manually do some state saving is if you want to restore state even after your application is killed.
You values still the same in your spinner because the app hasn't been kill yet. It's only put a pause state still in memory. If the app were destroyed the values of your spinner will be back to the onCreate method and whatever value they had at the start.
Look here for what each method does --> https://developer.android.com/reference/android/app/Activity.html
You only need to save state when onDestroy() is called. That only happens when you use the back button or the OS kills the Activity when it is in a stopped state.
If you Activity becomes partially obscured it will be paused but if it is completely obscured it will be stopped.
When it is top of the stack again it will resume or start.
To experiment use Log to write messages to the LogCat when each of events occurs and then you will be able to see when and why they are called.
Related
I'm like an intermediate in android programming. I decided to take a deep dive into the Activity lifecycle methods and I realised something, like why do methods Toasts.show() and many other methods get called again when the activity is resumed. If the methods are in the onCreate so why then if you like go to another activity and return it will still give you a Toast message. Let me give an example.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
{Your Initialization go here }
//Toas message
Toast.makeText(code).show();
}
}
So imagine you leaving this activity for another one and then coming back... why does it still show the Toast message. Because since the lifecycle is
OnCreate
onResume
onStart
onPause
onstop
onDestroy
And when you come back to your MainActivity it calls the
onResume
onStart.
So if onCreate is not called...So how does the Toast message show.
Please someone should help me answer this I've searched all day but couldn't find answers.
accoording to lifecycle of activity https://developer.android.com/guide/components/activities/activity-lifecycle, if there is no memory engouh the app process will kill, so when you back to your activity on created will call another time.
the image below for clarification:
When your activity goes in the background, and memory is required for other apps. It is possible that the system frees up space even though your activity is in the background with ONPAUSED state. and now if you navigate to your activity, since the saved instance is removed due to memory requirements. instead of ONRESUME, ONSTART is called. you can read more about it here: https://developer.android.com/guide/components/activities/activity-lifecycle
and see this image for better understanding: https://developer.android.com/guide/components/images/activity_lifecycle.png
This uncertainty is one of the reasons why we now mostly use view models for a sizeable app.
I want to run some code after I hit my home button and the re-open the app. How do I run code when the app is re-opened (Not After Being Killed) in android-studio?
you can use onStop() method or onDestroy() , if you will close totally that Activity use onDestroy() and if you just will put it in background you can use onStop()
Doc for onDestroy()
Perform any final cleanup before an 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.
Doc for onStop()
Called when you are no longer visible to the user. You will next
receive either onRestart(), onDestroy(), or nothing, depending on
later user activity.
i saw you edited your question, look at the lifecycle
Like sagar says, you can use onResume() in order to recover your current Activity
You can perform the action in onResume() method. This is the state in which the app interacts with the user. The app stays in this state until something happens to take focus away from the app. Do note that there is no differentiation between Activity coming from background to foreground or Activity created from scratch. onResume() will be called whenever app enters foreground state.
In order to differentiate it in onResume() you need to maintain a boolean flag. You can set the flag in onStop() and check it in onResume().
This approach will only work, if the OS hasn't killed the process, hosting your Activity, due to memory constraints. In this case your Activity will be recreated.
You can use onRestart() since when you left your activity to go home it goes into onStop() and after that when you launch it system will call onRestart() the onStart().
for more info refer following ans:
https://stackoverflow.com/a/35476531/7271231
I am developing an Android app in which I want to check if the user has minimized the application or just come from another activity.
In detail, if the user have started another app, went to the home screen or locked the screen, I want to show the activity where the user will enter the password to access the app. But where or how to check this exactly?
https://developer.android.com/guide/components/activities/activity-lifecycle.html
I was trying onResume() but according to documentation onResume() can be fired if the user’s navigating to another activity and coming back.
I'm not very clear on what you are trying to achieve.
The life cycle diagram is quite clear if you are wondering which lifecycle method it would hit when something happens.
Basically, it's the same to minimise the app and go to another activity. But if you are referring to coming from another activity in your own app, you can distinguish your own activity by adding extra information to the intent you use.
Basically, it's like this:
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra(key,value);
startActivity(intent);
And in your SecondActivity, you can always retrieve that data like this:
Bundle bundle = getIntent().getExtras();
if ( bundle != null && bundle.containsKey(key) ) {
value = bundle.getInt(key); // not nessecarily getInt(), you should use according to your value type
// use the value to tell if it is from your own app
} else {
// it is not from your own app
}
You can use this mechanism combined with the lifecycle methods. For example, if you use the latter code in your onCreate() method, then whenever the Activity is created, if will check who creates it, which sounds like your what you might want.
As soon as your activity becomes visible it will call OnStart() and as soon as it is ready for the interaction(such as touch ,click etc event). it calls onResume, at this stage your app is running and it is completely in foreground. When your activity start another activity or a dialog box then it calls onPause it means activity is visible but user can not interact with the Activity UI. in case we start another Activity which completely hides the previous activity then its onStop method is called
onPause: Called when another activity comes into the foreground.
onStop: Called when that other activity is completely visible.
onResume: Called when your activity is navigated back to from the onPause state.
Maybe your app was already in the onStop state, so then it would call onRestart.
I am developing an application in Android which has several Activities and need to check some details only when application is minimized and maximized, not on Activity screens' navigation. onPause() and onResume() doesn't work. onWindowFocusChanged() also doesn't helped as that is also calling while navigating among screens. Please help in which way I can be able to get an event only when Application is minimized/maximized, not on screen navigation.
I think that this Activity callback onUserLeaveHint() could be a start.
from the doc:
Called as part of the activity lifecycle when an activity is about to
go into the background as the result of user choice. For example, when
the user presses the Home key, onUserLeaveHint() will be called, but
when an incoming phone call causes the in-call Activity to be
automatically brought to the foreground, onUserLeaveHint() will not be
called on the activity being interrupted. In cases when it is invoked,
this method is called right before the activity's onPause() callback.
This callback and onUserInteraction() are intended to help activities
manage status bar notifications intelligently; specifically, for
helping activities determine the proper time to cancel a notfication.
It's not something which is common on Android, so I would agree to CommonsWare, that you should consider a different approach.
Nevertheless, there is a (bit hacky) way to achieve this.
Override onStop() and onResume() in every of your activities, set a boolean to true in onResume() and to false in onStop(). If this is true, the application is active, if it's false it's not.
You could use a listener, which is always called after the boolean value is set, to execute your actions.
If you can add a property, let's name it isShown in your customized Application object, which means you need extend the application for this purpose. it is in your subclass of Application and it is a signleton.
Be realized the lifecycle methods for onPause and onResume, when the onPause is called, it means the activity would be going to background, invisible any more, or put into the the activity stack. onResume means the activty status is recovered and ready for the user's interaction. So if you set the isShown property to false, which is in your application object, within the activity's onPause, and set it back to true in your onResume. of cause, you can make this behavior to be extracted into a superclass for the reuse purpose.
with the composite of onPause and onResume, and a given time we can identify the min/maxmized status. Let's say, isShown is set to false for a while, we can say it is minimized. otherwise, we can explain the maximized too.
But what are you going to do with this flag? did you still have a Service running in backend ready to receive this property to do something?
Over the past months I have been developing a versatile real-time game engine, and I have learned a lot, but I still feel very naive when it comes to the application life cycle. Specifically, I am trying to implement an Activity which can be shuffled in to the background by the user, then properly resumed.
My current architecture is as such: I have a an XML menu launcher activity which can create a real-time Game activity using intent. Relevant data in this Game activity is referenced through static data structures and variables. The Game activity creates worker threads in the onSurfaceCreate() callback of my SurfaceView object.
When a user presses the back button, the activity is destroyed, and they are sent back to the XML menu in the launcher activity. Fine, good for now. When the user presses the home button, the Activity is sent to the background. OK, great. My problems arise when the user tries to find their way back in the Game activity once is has been sent to the background. When the user touches the launcher icon, the Game is destroyed and the menu is re-launched. Also, when the user resumes the game through the task manager, the onSurfaceCreate() callback fires and the worker threads are started, but the game is frozen.
So, I have two questions. First, how do I resume my activity through the launcher icon, instead of re-launching the game? Second, when I resume my activity, what actions are necessary to restart my worker threads while persisting the game data?
Thanks!
EDIT: By request, I am including some code below. My onSurfaceCreate is a little bit complicated, it sends a message to another thread, which then implements the callback. I have verified that this implementation function fires when the Game activity is resumed.
protected void surfaceCreate()
{
Log.e(TAG, "surfaceCreate");
Thread gameThread = createGameThread();
gameThread.start();
}
protected final void onResume()
{
super.onResume();
resume();
}
protected final void onPause()
{
super.onPause();
pause();
}
These cryptic pause() and resume() methods simply set a boolean variable which prevents some game logic from being executed, they do nothing to hinder the worker threads, which should continue looping.
EDIT: Thanks Mohammad, for solving my first (although smaller) problem. It turns out that the launcher icon behaves differently when not connected by USB to the IDE. The second problem remains unresolved.
EDIT: All working! The second problem turned out to be an issue unique to my code, I apologize for that. I hope that this question can still be useful for those dealing with the launcher and IDEs.
There are multiple possible problems/solutions listed in this post. This includes misunderstanding of activity lifecycle and launchMode settings.
First, how do I resume my activity through the launcher icon, instead
of re-launching the game?
You are most likely missing definition for your onResume() and onPause() methods. Examples are here:
http://developer.android.com/training/basics/activity-lifecycle/pausing.html
Straight from the API:
onPause() Called as part of the activity lifecycle when an
activity is going into the background, but has not (yet) been killed.
onResume() Called after onRestoreInstanceState(Bundle),
onRestart(), or onPause(), for your activity to start interacting with
the user.
Check the Android Activity Lifecycle out:
http://developer.android.com/reference/android/app/Activity.html
One theory on your issue may be is that you're most likely going to onStop() (by hitting the home button) and the Android OS is looking for your onRestart(), but can't find it hence freezing/restarting.
Second, when I resume my activity, what actions are necessary to
restart my worker threads while persisting the game data?
Careful how you use the word restart. You want to pause and resume the application (not restart). Save data in onPause() (use a database or any other save feature you'd like). Load data in onResume(). Although, the activity should resume as normal if you just fill up these methods.
Now, if you want to save state for when you restart the application, you should save states in onStop() and/or onDestroy(). You should load states in onStart(). In order to save states, you can check this out:
https://stackoverflow.com/a/151940/2498729
For those using Eclipse (or any other IDE to run/test your application):
From what have you described you probably have overridden
android:launchMode in AndroidManifest.xml or if you are testing by
"run as" from Eclipse try exiting the application after installing and
auto-starting. Then start again from the emulator and test the Home
button behavior. I suppose this is because Android does not put
Activities on the OS stack when started from Eclipse and then the Home
button behavior is not as usual. If this does not solve your problem,
try reading
http://developer.android.com/guide/topics/fundamentals.html#lmodes.
I had launchMode set in my StartupActivity. THen I removed that (it
was set to "singleTask", it behaves like I want it; the app is
"resumed" to the Activity I expect, ie not StartupActivity but
MainActivity.
Source:
https://stackoverflow.com/a/1619461/2498729
http://developer.android.com/guide/topics/manifest/activity-element.html
According to this:
https://stackoverflow.com/a/3002890/2498729
You should change your andoird:launchMode to "Standard" (or "default").
Standard: A > B > HOME > B (what you want)
SingleTask: A > B > HOME > A (what you don't want)