Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android,Activity的生命周期

Android,Activity的生命周期

編輯:關於Android編程

啟動或結束一個Activity,我們就要跟它的生命周期打交道,安卓程序猿根據Activity的生命周期中各回調方法的觸發時機處理對應的業務邏輯,以保證用戶與頁面之間能正常良好地交互。

\

 

這張圖片多少人已經看爛了,不過還是可以拿來參考。這是Activity的XML

 


    
    
然後是JAVA代碼

 

 

public class LifeCycleActivity extends Activity {

	private EditText medit;
	private String s_txt;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.e("LifeCycleActivity-", "onCreate");
		setContentView(R.layout.activity_lifecycle);
		medit = (EditText) findViewById(R.id.m_edittext);
		findViewById(R.id.m_btnext).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent ite = new Intent(LifeCycleActivity.this, LifeJumpActivity.class);
				startActivity(ite);
			}
		});
	}
	
	//是否按了鍵盤返回鍵
	@Override
	public void onBackPressed() {
		Log.e("LifeCycleActivity-", "onBackPressed");
		super.onBackPressed();
	}
	
	@Override
	protected void onDestroy() {
		Log.e("LifeCycleActivity-", "onDestroy");
		super.onDestroy();
	}
	
	@Override
	public void onLowMemory() {
		Log.e("LifeCycleActivity-", "onLowMemory");
		super.onLowMemory();
	}
	
	@Override
	public void onTrimMemory(int level) {
		Log.e("LifeCycleActivity-", "onTrimMemory");
		super.onTrimMemory(level);
		Log.e("onTrimMemory-", "level:"+level);
		switch(level) {
		case TRIM_MEMORY_COMPLETE:
			Log.e("onTrimMemory-", "內存不足,並且該進程在後台進程列表最後一個,馬上就要被清理");
			break;
		case TRIM_MEMORY_MODERATE:
			Log.e("onTrimMemory-", "內存不足,並且該進程在後台進程列表的中部");
			break;
		case TRIM_MEMORY_BACKGROUND:
			Log.e("onTrimMemory-", "內存不足,並且該進程是後台進程");
			break;
		case TRIM_MEMORY_UI_HIDDEN:
			Log.e("onTrimMemory-", "內存不足,並且該進程的UI已經不可見了");
			break;
		case TRIM_MEMORY_RUNNING_CRITICAL:
			Log.e("onTrimMemory-", "內存不足(後台進程不足3個),並且該進程優先級比較高,需要清理內存");
			break;
		case TRIM_MEMORY_RUNNING_LOW:
			Log.e("onTrimMemory-", "內存不足(後台進程不足5個),並且該進程優先級比較高,需要清理內存");
			break;
		case TRIM_MEMORY_RUNNING_MODERATE:
			Log.e("onTrimMemory-", "內存不足(後台進程超過5個),並且該進程優先級比較高,需要清理內存");
			break;
		}
	}
	
	@Override
	protected void onPause() {
		Log.e("LifeCycleActivity-", "onPause");
		super.onPause();
		s_txt = medit.getText().toString();
	}
	
	@Override
	protected void onRestart() {
		Log.e("LifeCycleActivity-", "onRestart");
		super.onRestart();
	}
	
	@Override
	protected void onResume() {
		Log.e("LifeCycleActivity-", "onResume");
		super.onResume();
		medit.setText(s_txt);
	}
	
	/*onPostResume出現在onResume後,實際開發應用*/
	/*@Override
	protected void onPostResume() {
		Log.e("LifeCycleActivity-", "onPostResume");
		super.onPostResume();
	}*/
	
	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		Log.e("LifeCycleActivity-", "onRestoreInstanceState");
		super.onRestoreInstanceState(savedInstanceState);
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		Log.e("LifeCycleActivity-", "onSaveInstanceState");
		super.onSaveInstanceState(outState);
	}
	
	@Override
	protected void onStart() {
		Log.e("LifeCycleActivity-", "onStart");
		super.onStart();
	}
	
	@Override
	protected void onStop() {
		Log.e("LifeCycleActivity-", "onStop");
		super.onStop();
	}
	
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		Log.e("LifeCycleActivity-", "onWindowFocusChanged");
//		Log.e("LifeCycleActivity-", "onWindowFocusChanged-hasFocus:"+hasFocus);
		super.onWindowFocusChanged(hasFocus);
	}
	
	/*屏幕的Activity加監聽屏幕屬性改變,發生改變則檢查當前是否全屏狀態。是全屏狀態發送,全屏的廣播消息,到監聽應用觸發操作。
	 *注意該判斷在屏幕切換橫豎屏是也會觸發,需要根據實際情況過濾橫豎屏切換的情況。*/
	@Override
	public void onWindowAttributesChanged(LayoutParams params) {
		Log.e("LifeCycleActivity-", "onWindowAttributesChanged");
		super.onWindowAttributesChanged(params);
		if (WindowManager.LayoutParams.FLAG_FULLSCREEN == getWindow().getAttributes().flags) {
            Log.e("LifeCycleActivity-","onWindowAttributesChanged()-FLAG_FULLSCREEN");
        }
	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		Log.e("LifeCycleActivity-", "onConfigurationChanged");
		super.onConfigurationChanged(newConfig);
	}
	
}

 

運行示例的代碼在真機上,各個生命周期的過程如下:

1,Activity創建到啟動:onCreate,onWindowAttributesChanged,onStart,onResume,onWindowFocusChanged
2,Activity從顯示到關閉:onBackPressed(按下手機返回鍵),onPause,onWindowFocusChanged,onStop,onDestroy

3,顯示的Activity按下home鍵:onPause,onWindowFocusChanged,onTrimMemory,onSaveInstanceState,onStop

4,按下home後再次回到此Activity:onRestart,onStart,onResume,onWindowFocusChanged

5,Activity裡定義了一個EditText,用戶按下了home鍵,Activity進入後台不可見,如果已經輸入過文字,用戶返回此Activity時希望EditText能顯示輸入的文字,此時就需要保存和讀取文字。保存EditText的文字可以在onSaveInstanceState和onPause裡保存,返回此Activity裡時可以在onRestart,onStart,onResume裡顯示保存的文字,這裡使用的是onPause保存,onResume顯示,因為從前面可以看到Activity調用onPause和onResume較為普遍,當然你可以選擇其他的時態,只要結果一樣就行。

6,從此Activity跳轉到新的Activity時:onPause,onWindowFocusChanged,onSaveInstanceState,onStop;
從新的Activity返回此Activity時:onRestart,onStart,onResume,onWindowFocusChanged

7,當Activity處於被覆蓋或後台不可見狀態,系統內存不足而干掉此Activity,而後用戶返回了此Activity:
onCreate,onWindowAttributesChanged,onStart,onResume,onWindowFocusChanged

以上7種是比較常見的生命周期過程,接下來再講一下各個時態方法調用的時機。

onCreate:Activity創建時被調用

onStart:Activity創建或者從後台重新回到前台時被調用

onRestart:Activity從後台重新回到前台時被調用

onResume:Activity創建或者從被覆蓋、後台重新回到前台時被調用

onPostResume:出現在onResume後,實際開發應用較少

onPause:Activity被覆蓋到下面或者鎖屏時被調用

onStop:退出當前Activity或者跳轉到新Activity時被調用

onDestroy:退出當前Activity時被調用,調用之後Activity就結束了

onWindowFocusChanged:Activity窗口獲得或失去焦點時被調用,在onResume或onPause之後

onSaveInstanceState:Activity被系統殺死時被調用,例如:屏幕方向改變時,Activity被銷毀再重建;

當前Activity處於後台,系統資源緊張將其殺死。另外,當跳轉到其他Activity或者按Home鍵回到主屏時

該方法也會被調用,系統是為了保存當前View組件的狀態。它在onPause之前被調用。

onRestoreInstanceState:Activity被系統殺死後再重建時被調用,例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處於後台,系統資源緊張將其殺死,用戶又啟動該Activity。這兩種情況下onRestoreInstanceState都會被調用,它的調用時機在onStart之後。

 

***onLowMemory和onTrimMemory系統內存優化方法

當某個Activity處於後台不可見狀態時,如果它帶有較多Bitmap、數組、控件等占用內存較大的資源,此時在onLowMemory或onTrimMemory方法中重寫方法來釋放占用過多的內存。稍微注意以下幾點:

1,OnLowMemory被回調時,已經沒有後台進程;而onTrimMemory被回調時,還有後台進程。
2,OnLowMemory是在最後一個後台進程被殺時調用,一般情況是low memory killer 殺進程後觸發;而OnTrimMemory的觸發更頻繁,每次計算進程優先級時,只要滿足條件,都會觸發。
3,通過一鍵清理後,OnLowMemory不會被觸發,而OnTrimMemory會被觸發一次。

 

*** Activity橫豎切換屏幕生命周期

 

新建一個Activity,名為LifeJumpActivity,代碼與LifeCycleActivity,只是多了重寫監聽屏幕橫豎屏切換的方法onConfigurationChanged,下面是代碼:

 

@Override
	public void onConfigurationChanged(Configuration newConfig) {
		Log.e("LifeJumpActivity-", "onConfigurationChanged");
		super.onConfigurationChanged(newConfig);
		switch (newConfig.orientation) {  
        case Configuration.ORIENTATION_PORTRAIT:
        	LifeJumpActivity.this.setContentView(R.layout.orientation_portrait);
            Log.e("onConfigurationChanged", "切換到豎屏");
            break;  
        case Configuration.ORIENTATION_LANDSCAPE:
        	LifeJumpActivity.this.setContentView(R.layout.orientation_landscape);
        	Log.e("onConfigurationChanged", "切換到橫屏");
            break;  
        }
	}

可以看到,切換豎屏時重設布局orientation_portrait,切換橫屏時則為orientation_landscape。

 

當次Activity並未在AndroidManifest.xml配置 android:configChanges="screenSize|orientation"時,Activity切換橫豎屏時是會調用到生命周期的。

1,當Activity切換橫豎屏時都會調用到如下生命周期:onPause,onSaveInstanceState,onStop,onDestroy,onCreate,onWindowAttributesChanged,onStart,onRestoreInstanceState,onResume,onWindowFocusChanged;而且此時setContentView方法無效。

2,當給此Activity添加了 android:configChanges="screenSize|orientation"屬性後,Activity自動捕捉到設備屏幕方向和大小的改變,此時Activity只調用了onConfigurationChanged方法,而setContentView此時有效。注意Android4.0以後要使Activity切換橫豎屏時不改變生命周期,必須為screenSize|orientation。

 

以上就是我復習總結的Activity生命周期,如有錯誤,敬請指正!

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved