編輯:關於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;
}
}
當次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生命周期,如有錯誤,敬請指正!
Android[安卓] 版Air Video 遠程播放電腦視頻
在蘋果的iOS下面,有個應用Air Video,可以在iOS下通過Wifi遠程直接播放電腦裡的視頻,而不需要把視頻復制到手機上再看。非常好用!最近用了Android的手
Android OpenGL ES 應用(二) 紋理
要是做復雜的OpenGL應用程序,一定會用到紋理技術。紋理說白了就是把圖片或者視頻圖像繪制到OpenGL空間中。因此紋理也有坐標系,稱ST坐標,或者UV&nb
Android文件的上傳和下載
一、---框架---1、新建一個布局文件,輸入我們想要使用的線程的個數,包括一個主布局文件和一個progressBar(1)一個包括三個控件的主布局(2)一個只包含Pro
Andorid自定義圓形漸變色進度條的從實現到開源
信自己也是一種信仰。寫在前面的話3月初我在自定義控件概述中挖下的幾個坑,前一段時間已經基本填完了,自定義控件的幾種實現方式也分別寫了demo來進行說明。今天我們來聊一聊
Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
compile 'com.android.suppo