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