天天看點

Android_Activity_Activity詳解1.Activity的概述2.Activity的建立3.Activity的啟動4.Activity的關閉5.管理Activity的生命周期6.儲存Activity的狀态7.runOnUiThread()

本博文為子墨原創,轉載請注明出處! http://blog.csdn.net/zimo2013/article/details/11896323

1.Activity的概述

Activity是一個應用元件,用以提供螢幕的互動界面。一個App通常包含多個Activity,其中一個特殊的Activity被指定為main Activity,當使用者首次啟動該App時,main Activity被首先呈現。一個Activity A可以啟動新的Activity B,Activity A将被壓入傳回棧中,當使用者按下後退鍵退出Activity B後,Activity A将重新獲得焦點。

2.Activity的建立

建立一個Activity應該繼承Activity或者是其子類(比如ListActivity),然後實作相應的回調方法,下面隻列舉2個較常見的需實作方法。

(1).onCreate()

實作該方法,初始化一些必須的元件,通過調用setContentView()加載定義好的UI布局xml檔案,使用findViewById(int)得到相應布局,可以完成事件的監聽初始化!等等操作

(2).onPause()

當一個Activity失去焦點時,該方法将被調用,但該Activity還沒被銷毀,這個方法應該儲存使用者的持久資料,比如将使用者的資料儲存至資料庫 xml檔案或者其它檔案中。

3.Activity的啟動

(1).startActivity(intent)

//1.start a new activity
Intent intent = new Intent();
intent.setClass(this, NextActivity.class);
startActivity(intent);
           

(2).startActivityForResult(intent, REQUEST_CODE)

private final static int REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
/*
 * 2.start a new activity by REQUEST_CODE and can get a resultCode/data
 * 	to execute onActivityResult() method
 */
	Intent intent = new Intent();
	intent.setClass(this, NextActivity.class);
	startActivityForResult(intent, REQUEST_CODE);
	finishActivity(REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	switch (requestCode) {
	case REQUEST_CODE:
		/*
		 * in NextActivity.java, setResult(Activity.RESULT_OK);
		 * and finish();
		 */
		if(resultCode == Activity.RESULT_OK){
			//do something
		}
		break;
	default:
		break;
	}
}
           

4.Activity的關閉

(1).finish()

通過調用Activity自身的finish()方法,來關閉目前的Activity對象
Activity.this.finish();
           

(2).finishActivity()

Activity A通過startActivityForResult(intent, REQUEST_CODE)啟動新的Activity B,在Activity B中可以結束Activity A對象
ActivityB.this.finishActivity(REQUEST_CODE);
           
但是在許多情況下,并不使用這些顯示的finish方法去結束一個activity,通常android系統去管理,不需要手動結束。如手動結束,将可能很影響使用者體驗,應盡量少調用!

5.管理Activity的生命周期

管理好activities的生命周期對于開發一個健壯靈活的app至關重要,首先介紹三個重要的狀态

(1).其中三種重要狀态

1).Resumed

activity處于最前端并且能夠得到使用者的焦點,可看着running狀态

2).Paused

activity啟動了一個dialog,先前的activity可見但是失去焦點,此時activity處于Paused狀态,該activity依然停留在記憶體中和依附在窗體管理器上,在系統可用記憶體極其低的時候才會殺死目前狀态的activity。

3).Stopped

activity A啟動了一個新的activity B,activity A完全不可見,但是依然停留在記憶體中,不依附在窗體管理器上,當系統需要記憶體時,将會殺死該activity,被殺死的機率比Paused狀态下的高!

(2).生命周期路線圖

Activity完整生命周期路線圖
Android_Activity_Activity詳解1.Activity的概述2.Activity的建立3.Activity的啟動4.Activity的關閉5.管理Activity的生命周期6.儲存Activity的狀态7.runOnUiThread()

1).entire lifetime

該周期下的activity從onCreate()被調用完成布局xml檔案加載 到 onDestroy()釋放所有資源. 

2).visible lifetime

該周期下的activity從onStart()到onStop(),經曆了Activity的可見到完全不可見的過程。可以在onStart()中注冊一個BroadcastReceiver,并在onStop()解除這個BroadcastReceiver.

3).foreground lifetime

該周期下的activity從onResume()到onPause(),目前的activity可見但是失去了焦點,比如彈出的一個AlertDialog.

(3).生命周期回調函數概述

注意:在實作某個生命周期回調方法時,應該調用父類的實作方法。
方法 描述 可否殺死 下個方法
onCreate() Activity第一次被建立的時候,調用該方法。比如加載布局檔案 設定監聽器等等,該方法接收一個Bundle對象,後面将談到該bundle對象為Activity資料狀态的儲存所起作用。 no onStart()
onRestart() 當activity已經停止即處于Stopped狀态後,重新調用onStart()之前會執行該方法 no onStart()
onStart() 在activity可見之前,調用該方法 no

onResume()

or

onStop()

onResume() 在activity能與使用者互動之前,調用該方法。該activity将位于棧頂并獲得焦點 no onPause()
onPause() 當将要啟動一個新的activity時,調用該方法。該方法主要用于送出使用者未儲存的資料為持久的,停止動畫。該方法将執行很快,因為下一個activity不能為resumed狀态,直到該activity的onPause()傳回 yes

onResume()

or

onStop()

onStop() 當activity将處于不可見狀态時,調用該方法。有可能因為銷毀目前activity或者打開了一個新的activity yes

onRestart()

or

onDestroy()

onDestroy() 當activity被銷毀之前(可能調用了finish())或者Android系統臨時銷毀對象節約記憶體時,執行該方法。 yes nothing

(4).Activity在啟動模式下的生命周期

關于activity在AndroidManifest.xml中配置了啟動模式後可能出現的生命周期

6.儲存Activity的狀态

當一個activity不在棧頂時,系統預設儲存activity的狀态資訊,但我們應該主動地在onPause()方法中儲存為持久的狀态資訊,因為使用者可能會退出應用。處在paused和stopped狀态下的activity對象依然儲存在記憶體中,然而Android系統在記憶體不足時将能夠殺死這些activity,以釋放記憶體。

當在一個Activity A上,啟動一個新的Activity B後,此時Activity A被壓入該任務的傳回堆中,如果此時系統出現記憶體不足的情況,它将銷毀Activity A,在對象完全銷毀之前調用了該activity的onSaveInstanceState()方法,該方法通過bundle對象儲存了與目前銷毀的Activity有關的資訊,用于儲存一些與目前activity有關的資訊,比如記錄控件的資訊CheckBox的選擇狀态(隻要控件在xml檔案布局中指定唯一的id,bundle就能記錄下狀态資訊,但是如果指定了id且設定android:saveEnabled="false",bundle将不能記錄該控件的狀态)。當使用者按下Back按鈕後,由于在傳回堆中依然儲存Activity A資訊,但是此時該對象并不存在,是以需要重新建立該Activity的執行個體化對象,将系統在銷毀A時生成的bundle傳入onCreate()中,進而Activity A的狀态恢複到銷毀前的。

//假設使用者旋轉了手機螢幕,此時Activity被銷毀,在onCreate方法中列印bundle為一下資訊
onCreate::
	[{android:viewHierarchyState=
	Bundle[{android:[email protected], 
		android:[email protected], 
		android:[email protected]}]}]
           

注意:并不是每個onSaveInstanceState()方法都能夠得到執行,如果一個使用者在退出activity後,系統能判斷該傳回堆中,已經到堆底,意味着該應用已經退出,故儲存activity的狀态已經沒有任何意義,故onSaveInstanceState()方法得不到執行!onSaveInstanceState()可能在onPause()之前執行,但是肯定在onStop()之前執行!儲存永久性的資料,應該在onPause()中操作,可以将資料儲存至資料庫或者xml等等!

如果存在一個Activity A,該對象中含有一個EditText控件,在該控件中鍵入一些字元,然後啟動了新的Activity B,一段時間後在Activity B通過back按鈕傳回至Activity A中,假設此時A對象并沒有被銷毀,EditText控件中的字元依然存在,在onSaveInstanceState()中并儲存bundle狀态,當activity壓入傳回棧後,又重新彈至棧頂時恢複原來的狀态!

/*
 * activity對象處于stopped前,執行onSaveInstanceState()方法,儲存相關控件的狀态資訊,
 * 	比如輸入字元,checkbox的選擇狀态等等
 */
onSaveInstanceState::
	Bundle[{android:[email protected], 
	android:viewHierarchyState=Bundle[{android:[email protected], 
		android:[email protected], 
		android:[email protected]}]}
           

7.runOnUiThread()

public final void runOnUiThread(Runnable action) {
	if (Thread.currentThread() != mUiThread) {
		mHandler.post(action);
	} else {
		action.run();
	}
}
           
主要用于彈出吐司
public void click(View view){
	final Runnable action = new Runnable() {
		
		@Override
		public void run() {
			Toast.makeText(MainActivity.this, "ok~~", 0).show();
		}
	};
	new Thread(){	
		public void run() {
			// 1.工作線程
			runOnUiThread(action);//由于該方法的執行實在工作線程中
		}
	}.start();
	
	// 2.工作線程
	runOnUiThread(action);//該方法在主線程中執行,可以彈出吐司
}