Managing the lifecycle of your activities by implementing callback methods is crucial to developing a strong and flexible application. The lifecycle of an activity is directly affected by its association with other activities, its task and back stack.
利用不同的實作方法去管理activities的生命週期對於開發來說是相當重要的並且讓應用程式更有彈性。activity的生命週期與其他的activity密不可分,是一種任務的堆疊(stack)。
An activity can exist in essentially three states:
- Resumed
- The activity is in the foreground of the screen and has user focus. (This state is also sometimes referred to as "running".)
- Paused
- Another activity is in the foreground and has focus, but this one is still visible. That is, another activity is visible on top of this one and that activity is partially transparent or doesn't cover the entire screen. A paused activity is completely alive (the
Activityobject is retained in memory, it maintains all state and member information, and remains attached to the window manager), but can be killed by the system in extremely low memory situations. - Stopped
- The activity is completely obscured by another activity (the activity is now in the "background"). A stopped activity is also still alive (the
Activityobject is retained in memory, it maintains all state and member information, but is not attached to the window manager). However, it is no longer visible to the user and it can be killed by the system when memory is needed elsewhere.
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its
Activity的3種狀態(state)finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.1.Resumed:
出現在螢幕的前景,也就是在目前task的activity堆疊的最上層,這Activity正被focus並接受使用者的動作
2.paused:
失去了focus,但使用者還是可以看到Activity,其他activity在其上方,也許是透明或沒有全螢幕覆蓋,因此paused的Activity還可以被看到。一個paused Activy還是在存活狀態(還保有所有資料,並被window manager所管理)但在系統記憶體過低時還是可能被砍掉
3.stopped:
當完全被其他的Activity所遮蔽,他是保有一些狀態資料,但已經看不到,他的視窗已經被隱藏,當系統記憶體過低會被砍掉。
當系統記憶體過低,會將屬於paused與stopped狀態的Activity 砍掉,也就是呼叫其finish()或直接就砍了其process,當要再重新顯示在使用者面前,需要完全restart並restore之前的state資料。
Implementing the lifecycle callbacks
When an activity transitions into and out of the different states described above, it is notified through various callback methods. All of the callback methods are hooks that you can override to do appropriate work when the state of your activity changes. The following skeleton activity includes each of the fundamental lifecycle methods:
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
Note: Your implementation of these lifecycle methods must always call the superclass implementation before doing any work, as shown in the examples above.
Taken together, these methods define the entire lifecycle of an activity. By implementing these methods, you can monitor three nested loops in the activity lifecycle:
- The entire lifetime of an activity happens between the call to
onCreate()and the call toonDestroy(). Your activity should perform setup of "global" state (such as defining layout) inonCreate(), and release all remaining resources inonDestroy(). For example, if your activity has a thread running in the background to download data from the network, it might create that thread inonCreate()and then stop the thread inonDestroy(). - The visible lifetime of an activity happens between the call to
onStart()and the call toonStop(). During this time, the user can see the activity on-screen and interact with it. For example,onStop()is called when a new activity starts and this one is no longer visible. Between these two methods, you can maintain resources that are needed to show the activity to the user. For example, you can register aBroadcastReceiverinonStart()to monitor changes that impact your UI, and unregister it inonStop()when the user can no longer see what you are displaying. The system might callonStart()andonStop()multiple times during the entire lifetime of the activity, as the activity alternates between being visible and hidden to the user. - The foreground lifetime of an activity happens between the call to
onResume()and the call toonPause(). During this time, the activity is in front of all other activities on screen and has user input focus. An activity can frequently transition in and out of the foreground—for example,onPause()is called when the device goes to sleep or when a dialog appears. Because this state can transition often, the code in these two methods should be fairly lightweight in order to avoid slow transitions that make the user wait.
每個Activity一定要Override onCreate()來作初始化功能,有的會需要override onPause()去把資料改變記錄下來,以因應可能停止的動作:
1.entire lifetime:
一個Activity由onCreate()開始,到最後onDestroy()結束,會在onCreate()時做所有初始化的動作,在onDestroy()內釋放所有的系統資源。例如有一個Thread在背景進行網路資料下載,這thread會在onCreat()程序內產生,而在onDestroy()停止這thread
2.visible lifetime:
由呼叫onStart()開始到 onStop()結束,在這過程使用者可以看到Activity在螢幕上,在這期間使用者可以看到元件顯示在畫面上,但不見得在前景或與使用者互動。例如你可以在onStart註冊一個BroadcastReceiver,而在onStop()中解除註冊,利用BroadcastReceiver監看UI上的變化,這樣就可
以觀察到相關的變化,在Activity運作上,onStart()與onStop()在進行中可以被多次呼叫
3.foreground lifetime:
由呼叫onResume()到onPause()間,在這區間,Activity在前景,並可與使用者互動。Activity經常在這兩個狀態間跳動。例如當Device進入睡眠狀態或另一個Activty要開啟,就會呼叫onPause(),而當activity繼續執行,或一個新的intent被發送出來Activity內的onResume()就會被呼叫執行
Figure 1 illustrates these loops and the paths an activity might take between states. The rectangles represent the callback methods you can implement to perform operations when the activity transitions between states.

Figure 1. The activity lifecycle.
The same lifecycle callback methods are listed in table 1, which describes each of the callback methods in more detail and locates each one within the activity's overall lifecycle, including whether the system can kill the activity after the callback method completes.
Table 1. A summary of the activity lifecycle's callback methods.
| Method | Description | Killable after? | Next | ||
|---|---|---|---|---|---|
| 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, and so on. This method is passed a Bundle object containing the activity's previous state, if that state was captured (seeSaving Activity State, later).
Always followed by
onStart(). | No | onStart() | ||
| Called after the activity has been stopped, just prior to it being started again.
Always followed by
onStart() | No | onStart() | ||
| Called just before the activity becomes visible to the user.
Followed by
onResume() if the activity comes to the foreground, or onStop() if it becomes hidden. | No | onResume()or onStop() | ||
| Called just before the activity starts interacting with the user. At this point the activity is at the top of the activity stack, with user input going to it.
Always followed by
onPause(). | No | onPause() | ||
| Called when the system is about to start resuming another activity. This method is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, and so on. It should do whatever it does very quickly, because the next activity will not be resumed until it returns.
Followed either by
onResume() if the activity returns back to the front, or byonStop() if it becomes invisible to the user. | Yes | onResume()or onStop() | ||
| Called when the activity is no longer visible to the user. This may happen because it is being destroyed, or because another activity (either an existing one or a new one) has been resumed and is covering it.
Followed either by
onRestart() if the activity is coming back to interact with the user, or by onDestroy() if this activity is going away. | Yes | onRestart()or onDestroy() | ||
| Called before the activity is destroyed. This is the final call that the activity will receive. It could be called either because the activity is finishing (someone called 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 method. | Yes | nothing | ||
The column labeled "Killable after?" indicates whether or not the system can kill the process hosting the activity at any time after the method returns, without executing another line of the activity's code. Three methods are marked "yes": (
onPause(), onStop(), and onDestroy()). Because onPause() is the first of the three, once the activity is created,onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() andonDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage. However, you should be selective about what information must be retained during onPause(), because any blocking procedures in this method block the transition to the next activity and slow the user experience.
Methods that are marked "No" in the Killable column protect the process hosting the activity from being killed from the moment they are called. Thus, an activity is killable from the time
onPause() returns to the time onResume() is called. It will not again be killable until onPause() is again called and returns.
Note: An activity that's not technically "killable" by this definition in table 1 might still be killed by the system—but that would happen only in extreme circumstances when there is no other recourse. When an activity might be killed is discussed more in the Processes and Threading document.
Activity LifeCycle Method狀態說明1.onCreate()
當activity第一次被產生後,會被執行。你可以在這程序內create View、bind data與list,在這method被執行時會接收到一個Bundle物件,這物件包含了Activity之前的state資料,接下來會執行的有onStart()
2.onRestart()
當Activity被停止後,又重新啟動時執行(與onStart同),接下來會執行的有onStart()
3.onStart()
在Activity要變成Visible前執行,如果接下來要把Activity顯示在前景,,則伴隨著onResume(),如果接下來要把Activity隱藏,則伴隨著onStop()
4.onResume()
在Activity開始與使用者互動前被呼叫,在這點Activity是在Activity堆疊的最頂端,接下來的會是onPause()
5.onPause()
當系統要啟動其他Activity,這程序會被呼叫,在這程序中需要去處理,把尚未儲存的資料儲存下來,停止動畫與其他會消耗CPU的動作,這過程需要非常快速,因為下一個Activity會等他return才會執行。若接下來這Activity要回到前景,接下來的會是onResume()、若接下來這Activity要變隱藏,則接下來會是onStop()
6.onStop()
當Activity不再讓使用者看到時呼叫,可能發生在這Activity準備要destroy或是其他的Activity回復到前景。假使這Activity要回到前景,接下來會是onResume();假若這Activity要整個關閉,接下來會是onDestroy()
7.onDestroy()
當Activity被Destroyed前被呼叫,這會是這Activity最後一個接收到通知,他可能發生在呼叫了finish()之後,或因為系統因為記憶體不足要節少空間而刪除,可以利用isFinishing()來判斷是
什麼原因造成
Saving activity state
The introduction to Managing the Activity Lifecycle briefly mentions that when an activity is paused or stopped, the state of the activity is retained. This is true because the
Activityobject is still held in memory when it is paused or stopped—all information about its members and current state is still alive. Thus, any changes the user made within the activity are retained in memory, so that when the activity returns to the foreground (when it "resumes"), those changes are still there.
Figure 2. The two ways in which an activity returns to user focus with its state intact: either the activity is stopped, then resumed and the activity state remains intact (left), or the activity is destroyed, then recreated and the activity must restore the previous activity state (right).
However, when the system destroys an activity in order to recover memory, the
Activity object is destroyed, so the system cannot simply resume it with its state intact. Instead, the system must recreate the Activity object if the user navigates back to it. Yet, the user is unaware that the system destroyed the activity and recreated it and, thus, probably expects the activity to be exactly as it was. In this situation, you can ensure that important information about the activity state is preserved by implementing an additional callback method that allows you to save information about the state of your activity and then restore it when the the system recreates the activity.
The callback method in which you can save information about the current state of your activity is
onSaveInstanceState(). The system calls this method before making the activity vulnerable to being destroyed and passes it a Bundle object. The Bundle is where you can store state information about the activity as name-value pairs, using methods such as putString(). Then, if the system kills your activity's process and the user navigates back to your activity, the system passes the Bundle to onCreate() so you can restore the activity state you saved during onSaveInstanceState(). If there is no state information to restore, then the Bundle passed toonCreate() is null.
Note: There's no guarantee that
onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the BACK key, because the user is explicitly closing the activity). If the method is called, it is always called before onStop() and possibly before onPause().
However, even if you do nothing and do not implement
onSaveInstanceState(), some of the activity state is restored by the Activity class's default implementation of onSaveInstanceState(). Specifically, the default implementation calls onSaveInstanceState() for every View in the layout, which allows each view to provide information about itself that should be saved. Almost every widget in the Android framework implements this method as appropriate, such that any visible changes to the UI are automatically saved and restored when your activity is recreated. For example, the EditText widget saves any text entered by the user and the CheckBox widget saves whether it's checked or not. The only work required by you is to provide a unique ID (with theandroid:id attribute) for each widget you want to save its state. If a widget does not have an ID, then it cannot save its state.
You can also explicitly stop a view in your layout from saving its state by setting the
android:saveEnabled attribute to "false" or by calling the setSaveEnabled() method. Usually, you should not disable this, but you might if you want to restore the state of the activity UI differently.
Although the default implementation of
onSaveInstanceState() saves useful information about your activity's UI, you still might need to override it to save additional information. For example, you might need to save member values that changed during the activity's life (which might correlate to values restored in the UI, but the members that hold those UI values are not restored, by default).
Because the default implementation of
onSaveInstanceState() helps save the state of the UI, if you override the method in order to save additional state information, you should always call the superclass implementation ofonSaveInstanceState() before doing any work.
Note: Because
onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity.
A good way to test your application's ability to restore its state is to simply rotate the device so that the screen orientation changes. When the screen orientation changes, the system destroys and recreates the activity in order to apply alternative resources that might be available for the new orientation. For this reason alone, it's very important that your activity completely restores its state when it is recreated, because users regularly rotate the screen while using applications.
Handling configuration changes
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (
onDestroy() is called, followed immediately by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that you've provided. If you design your activity to properly handle this event, it will be more resilient to unexpected events in the activity lifecycle.
The best way to handle a configuration change, such as a change in the screen orientation, is to simply preserve the state of your application using
onSaveInstanceState() andonRestoreInstanceState() (or onCreate()), as discussed in the previous section.
For a detailed discussion about configuration changes that happen at runtime and how you should handle them, read Handling Runtime Changes.
Coordinating activities
When one activity starts another, they both experience lifecycle transitions. The first activity pauses and stops (though, it won't stop if it's still visible in the background), while the other activity is created. In case these activities share data saved to disc or elsewhere, it's important to understand that the first activity is not completely stopped before the second one is created. Rather, the process of starting the second one overlaps with the process of stopping the first one.
The order of lifecycle callbacks is well defined, particularly when the two activities are in the same process and one is starting the other. Here's the order of operations that occur when Activity A starts Acivity B:
- Activity A's
onPause()method executes. - Activity B's
onCreate(),onStart(), andonResume()methods execute in sequence. (Activity B now has user focus.) - Then, if Activity A is no longer visible on screen, its
onStop()method executes.
This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another. For example, if you must write to a database when the first activity stops so that the following activity can read it, then you should write to the database during
onPause() instead of during onStop().
0 comments:
Post a Comment