I noticed that the Android Developers Activity section has been updated since I started my app, but I am still unclear what the simplest Activity Lifecycle is.
As far as I can make out:
onCreate, onResume and onPause are the essential ones.
The activity may be deleted any time after onPause, so I should save my whole app state to a file onPause and not rely on onStop or onDestroy. Also, onSaveInstanceState is not called before every onPause so is not really worth using.
Rather than trying to write loads of code to handle all the scenarios, why not destroy the Activity at the end of its onPause?
The Lifecycle would then be onCreate and onResume before it is active, then onPause when it becomes inactive. Other methods would not be needed.
I'd use onCreate to call setContentView and set up view listeners, but everything else would be put in onResume, including loading the restored state from a file? As stated earlier, onPause would save the state to a file and destroy the activity.
As far as I can see, the only disadvantage of this might be that when a popup is on screen, the activity is deleted and has to be recreated when the popup is closed, meaning the activity won't be visible behind the popup (although I have not tested this)
It may take a bit longer to restart the activity, but since the system could have deleted the activity anyway without any notice, you have to save the whole state anyway.
Any thoughts?
Update: I suppose what I was thinking of was where a 'front page' activity calls a game activity. The frontpage activity would call the game activity when the player clicks 'Play'
The game activity would set up its views and listeners etc. in onCreate, and in onResume it would load a file containing the game state, or start a new game if no file existed.
onPause of the game, it writes the game state to the file, then whatever happens to the game activity (nothing, or gets stopped/destroyed, or whatever) the onResume method would always load all the data back in again from the file.
That's 开发者_如何学编程sort of what I was thinking, if that makes any sense?
Update2: I've devised a simple solution which I've documented in an answer below, if anyone's interested!
It doesn't support the Android Activity Lifecycle 'Paused' and 'Stopped' states. Once it is no longer displayed it kills itself and has to be restarted manually, but it does carry on from where you left off!
Are you looking for this?
To further answer your question, yes, as you can plainly see from the above diagram the "simplest" (i.e. smallest number of method calls) lifecycle is indeed onCreate(); onStart(); onResume(); onPause();
.
You should also know about onSaveInstanceState()
and onRetainNonConfigurationInstance()
. These are NOT lifecycle methods.
All these methods are very well documented. Please read this documentation thoroughly.
To clarify things further, here are a couple of real-life scenarios:
- Activity is running, other activities come on top of it,
onPause
is called. System runs out of memory, callsonSaveInstanceState
, kills activity. User pressed back a few times, activity has to be re-instantiated (preferably using the data saved inonSaveInstanceState
). - Activity is running, user presses back. At this point
onPause->onDestroy
are called, without callingonSaveInstanceState
.
You should understand the essential difference between onPause
and onSaveInstanceState
. The former is always called, while the latter is only called when the activity instance might be re-instantiated in the future. Following this train of thought, your users will expect two things:
- When they navigate away from your Activity and later come back to it, they want it in the exact same instance that they left it (this would be achieved using
onSaveInstanceState
). They don't expect that if they exit your activity. However: - They will expect that data they have entered will be persisted (which will be done in
onPause
). For example, if they started composing a message, they'll expect to see it as a draft the next time they come back, even if they exited the activity.
You should understand how these methods are supposed to be used in order to get what your users expect. How you actually use them is up to you, your needs, and your app's nature.
Android system is handling the lifecycle: i.e. instantiating activities and calling lifecycle methods. So I don't know what you mean by "destroy the activity". You, as a developer, have no such ability.
Second, activity lifecycle flow can be sometimes confusing (I know I struggled with it at the beginning). So, just implement all lifecycle methods and put logging statements in them. Then try all real-life use cases (including receiving a call during app use) to see how lifecycle methods are called.
I was studying the activity life cycle and the complete process of what happens when you start any activity, starting from onCreate
. Here is a UML diagram to help you.
Click this link to see a High Resolution version.
The answer is as simple as the life cycle. Only override callbacks when you need to handle stuff in there.
Android will always call every callback how it is supposed to, except in certain circumstances.
Just because certain callbacks are not guaranteed to be called doesn't mean that they are useless. Just don't try to handle sensible stuff in such callback methods.
onCreate() obviously first. Your activity can then enter onPause(). From there it could either onResume() or onDestroy(). That's the simplest path through the lifecycle that I know of.
I had an activity that didn't have an onPause() method. Through an odd series of events I noticed in DDMS that my app wasn't visible, but it was still requesting freshAds from AdMob :) Nice battery sucker. That's since been resolved but reminded me how important the simple things are.
I think I have found what I am looking for! (Me 1, Bono 0)
This is for a single 'Game' activity which uses minimum methods to control a 'GameThread' thread which handles the game. It uses an additional 'GameData' class to hold data which is required to be persistent between activations.
If the app loses focus (i.e. an incoming phone call, or the user clicks back etc.), Game saves the GameData to a file and exits. To resume, just start the app again and it goes right back to where you left off.
The layout file 'game.xml' is a SurfaceView covering the whole screen
Game.java:
- onCreate sets up the SurfaceHolder for the SurfaceView and creates the GameThread
- surfaceChanged calls GameThread.startThread to start the GameThread, if not already started, passing the screen size
- onPause calls GameThread.endThread to end the GameThread and ends this activity
- onTouch passes touch events to the GameThread.doTouch method
GameThread.java:
- startThread sets up locally held data, loads GameData from file and starts the thread
- run is a standard game loop, calling fairly standard updatePhysics and drawScreen routines for each frame. After the game loop finished it saves the GameData to the file
- endThread stops the game loop in run and waits for it to finish
- doTouch actions touch events from the Game activity
It seems to work. It does mean having to handle different screens (e.g. title screen, options, play and game over) in the one thread, but that's not the end of the world, IMHO.
Maybe I'll publish the code on CodeReview (I'll update this if I do) and see if anyone's got any comments. Meanwhile, I'd better get coding the next Angry Birds!
What i personally think is developer should divide the work into different states of the activity. Sequence of the work must be retained in this case what is more importent I think of and this is why because Android can't handle a long UI processing in a single thread & it gives error that Android have 'so much work to do' in this reference that could be cause of getting crash sometimes So we should prevent to write whole code in a section. The code would be written into difference functions or classes and we can derive these functions as per requirement. Thanks.
There are 7 methods that manage the activity lifecycle in Android application:
- onCreate()
- onStart()
- onResume()
- onRestart()
- onPause()
- onStop()
- onDestroy()
I have written more in-depth about these methods on my blog
The mature, full-featured and full functional Android app gets transitioned (state = function of time) according to the answer provided by @Felix.
But what if you just want to create an app which doesn't even have GUI. And you want the simplest lifecycle then I have the answer below.
This answer probably you would find interesting. Android system after reading AndroidManifest.xml knows which is entry point. Whichever activity has this
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
will be the starting or entry point for the system to start with. After this, your app process got the memory where it can start itself.
Your main process creation is the task of Android system. When an application component starts and the application does not have any other components running, the Android system starts a new Linux process. After the process calls the onCreate(), it creates main thread. That's the reason why you must call onCreate(), because the main thread is then initialized and the main thread is the trigger for all of your future actions.
On onCreate(), you got your main thread. After that, it is totally up to you, what callbacks you want to call. There is no rule you must call onStart() after onCreate().
Only one lifecycle method onCreate() is guaranteed to be your component's life cycle back.
And, furthermore, to understand, what each lifecycle method is doing inside it, put the below code.
//add the log line
Log.i(this.getClass().getCanonicalName(), "##############");
int count = 0;
for (StackTraceElement stackTraceElement: Thread.currentThread().getStackTrace()) {
count++;
Log.i(this.getClass().getCanonicalName(), "\""+Thread.currentThread().getStackTrace()[2].getMethodName()+"\" "+count+" "+stackTraceElement.getMethodName());
}; //end of log line
So, always add above same code to view logs in log cat console.
When your app starts GUI, it calls onStart(). If you don't call super() method inside the callback, android system shows broken pipe error and it can't do further processing and debugging.
But, you can implement your own logic inside each callback method. Eg, you can do summation of two numbers on onStart().
So, all android callback methods are partially implemented methods. They are not purely abstract methods because you should call the super() method inside them.
The attached picture tells: Application main process calls onCreate(), it delegates it's responsibilities to main thread (UI thread) and main thread calls these 16 other callbacks.
Further, if you would like to see all of your methods at particular time, put this below code.
//to see all the methods (including super methods) at this time, you call use the java reflection as below
Log.i(this.getClass().getCanonicalName(), "##############");
int count1 = 0;
for (Method method: this.getClass().getMethods()) {
count1++;
count++;
Log.i(this.getClass().getCanonicalName(), count1+" "+method);
}; //end of log line
//At another time, after you add some other methods or android using GC removes some methods, you see your changed state (Bundle Snapshot) of your class
//Because your bundle (i.e, the state of your class/activity) is the function of time.
In my scenario, from the just above code snippet, I see it has called 375 methods.
Note: If you had added another method inside onCreate() before you print all of your methods using just above code snippet, you would have seen that method as well. It means, your state of the class (i.e., snapshot) is according to you, what you do time after time, you keep updating your snapshot.
精彩评论