android初學(xué)者必須掌握的Activity狀態(tài)的四大知識(shí)點(diǎn)(必讀)
這幾天一直都在搗鼓android的知識(shí)點(diǎn),興趣班的老師,講課太過(guò)深?yuàn)W,天(想到什么就見(jiàn)什么,后后面完全不想聽(tīng)),最后自己找資料總結(jié)了在Android中很重要的一個(gè)組件Activity,那就開(kāi)始吧!
第一:掌握Activity的四種狀態(tài)及什么時(shí)候觸發(fā)
首先我們要知道什么是Activity,簡(jiǎn)單來(lái)說(shuō)Activity其實(shí)就是一個(gè)屏幕的顯示頁(yè)面。(簡(jiǎn)單的闡述)
我們知道Activity是由Activity棧進(jìn)管理,當(dāng)來(lái)到一個(gè)新的Activity后,此Activity將被加入到Activity棧頂,之前的Activity位于此Activity底部。
Acitivity一般意義上有四種狀態(tài):
1、Running狀態(tài): 一個(gè)新的Activity啟動(dòng)入棧后,它在屏幕的最前端,處于棧的最頂端,此時(shí)它處于可見(jiàn)并可和用戶交互的激活狀態(tài),Android試圖盡最大可能保持它活動(dòng)狀態(tài),殺死其它Activity來(lái)確保當(dāng)前活動(dòng)Activity有足夠的資源可使用。當(dāng)另外一個(gè)Activity被激活,這個(gè)將會(huì)被暫停。
2、Paused狀態(tài):當(dāng)Activity處于此狀態(tài)時(shí),此時(shí)它依然與窗口管理器保持連接,系統(tǒng)繼續(xù)維護(hù)其內(nèi)部狀態(tài),它仍然可見(jiàn),但它已經(jīng)失去了焦點(diǎn),故不可與用戶交互。
3、Stopped狀態(tài): 當(dāng)Activity 不可見(jiàn)時(shí),Activity處于Stopped狀態(tài)。當(dāng)Activity處于此狀態(tài)時(shí),一定要保存當(dāng)前數(shù)據(jù)和當(dāng)前的UI狀態(tài),否則一旦Activity退出或關(guān)閉時(shí),當(dāng)前的數(shù)據(jù)和UI狀態(tài)就丟失了
4、Killed狀態(tài): Activity被殺掉以后或者被啟動(dòng)以前,處于Killed狀態(tài)。這是Activity已從Activity堆棧中移除,需要重新啟動(dòng)才可以顯示和使用。
對(duì)四種狀態(tài)的一個(gè)總結(jié):Running狀態(tài)和Paused狀態(tài)是可見(jiàn)的,Stopped狀態(tài)和Killed狀態(tài)時(shí)不可見(jiàn)的,當(dāng)然Starting是有系統(tǒng)自身自動(dòng)創(chuàng)建,而且每一個(gè)活動(dòng)( Activity )都處于某一個(gè)狀態(tài),對(duì)于開(kāi)發(fā)者來(lái)說(shuō),是無(wú)法控制其應(yīng)用程序處于某一個(gè)狀態(tài)的,這些均由系統(tǒng)來(lái)完成。
但是當(dāng)一個(gè)活動(dòng)的狀態(tài)發(fā)生改變的時(shí)候,開(kāi)發(fā)者可以通過(guò)調(diào)用 onXX() 的方法獲取到相關(guān)的通知信息。
接下來(lái)講下各種狀態(tài)在何時(shí)觸發(fā):
1、Running狀態(tài):
期間觸發(fā)的函數(shù)及順序?yàn)椋?onCreate() ->on Start() -> onResume()。
注意:
1.1:onCreate()只有在該Activity是第一次被創(chuàng)建時(shí)才會(huì)被調(diào)用,主要是負(fù)責(zé)Activity的一般性的初始化設(shè)置,包括視圖的創(chuàng)建,數(shù)據(jù)的綁定等等。
需要注意的是若之前有凍結(jié)的state(即系統(tǒng)對(duì)該Activity調(diào)用過(guò)onSaveInstanceState()函數(shù)),則可以通過(guò)其 Bundle 參數(shù)進(jìn)行state恢復(fù)。
1.2:on Start()是當(dāng)Activity正在變?yōu)榭梢?jiàn)狀態(tài)時(shí)才會(huì)被調(diào)用。一般地在此期間可以注冊(cè)一個(gè)廣播等等。
1.3:onResume()是在該Activity將要和用戶進(jìn)行交互時(shí)被調(diào)用,此時(shí)Activity位于的活動(dòng)棧頂部。
2、Paused狀態(tài):
運(yùn)行狀態(tài)到暫停狀態(tài)所觸發(fā)的函數(shù)及順序?yàn)椋簅nResume() -> onPuased()
暫停狀態(tài)恢復(fù)至運(yùn)行狀態(tài)所觸發(fā)的函數(shù)及順序?yàn)椋簅nPuased() -> onResume()。
注意:
2.1:onPuased()是當(dāng)一個(gè)Activity失去系統(tǒng)焦點(diǎn)后將會(huì)被調(diào)用,包括見(jiàn)面被部分遮擋,以及設(shè)備轉(zhuǎn)入休眠狀態(tài)等等。一般地在此期間對(duì)一些未保存的數(shù)據(jù)進(jìn)行持久化并停 止其他需要耗費(fèi)CPU的操作,同時(shí)不可進(jìn)行耗時(shí)操作,否則會(huì)阻塞系統(tǒng)UI線程。
2.2:一個(gè)處于暫停狀態(tài)的Activity只有在系統(tǒng)極度缺乏內(nèi)存資源的情況下才會(huì)被系統(tǒng)強(qiáng)制結(jié)束。
3、stopped狀態(tài):
暫停狀態(tài)到停止?fàn)顟B(tài)所觸發(fā)的函數(shù)及順序?yàn)椋簅nPuased() -> on Stop()。
停止?fàn)顟B(tài)恢復(fù)至運(yùn)行狀態(tài)所觸發(fā)的函數(shù)及順序?yàn)椋簅n Stop() -> onRestart() -> on Start() -> onResume()。
注意:
3.1:on Stop()是當(dāng)一個(gè)Activity變?yōu)椴豢梢?jiàn)時(shí)將會(huì)被調(diào)用,此時(shí)可能是由于該Activity要被注銷(xiāo)或新的Activity完全遮擋了該Activity。在此期間一般可以進(jìn)行取消注冊(cè) 廣播等操作,因此用戶不可見(jiàn)。
3.2:onRestart()是當(dāng)一個(gè)Activity從停止?fàn)顟B(tài)恢復(fù)至運(yùn)行狀態(tài)時(shí)將會(huì)被優(yōu)先調(diào)用。
4、Killed狀態(tài):
停止?fàn)顟B(tài)到死亡狀態(tài)分為兩種情況:(1)由用戶操作導(dǎo)致,則執(zhí)行:on Stop() -> onDestroy()。
(2)由系統(tǒng)自動(dòng)強(qiáng)制執(zhí)行,則該Activity被強(qiáng)行結(jié)束。
注意:
4.1:onDestroy()是當(dāng)一個(gè)Activity正在被系統(tǒng)finished期間被調(diào)用的。
第二:掌握Activity的生命周期及各個(gè)階段觸發(fā)的事件名稱和觸發(fā)次數(shù)
Activity一共有七個(gè)生命周期函數(shù),分別為onCreate(),onRestart(),on Start(),onReusme(),onPause(),on Stop(),onDestory()。
1:onCreate()
當(dāng)Acitivity第一次被創(chuàng)建時(shí)觸發(fā),一般在這里要做的事情包括創(chuàng)建視圖(setContentView())、向視圖填充必要的數(shù)據(jù)等等。
2:onRestart()
如果Activity之前被stop過(guò),那么下一次onStart()方法之前會(huì)先觸發(fā)這個(gè)方法,當(dāng)處于停止?fàn)顟B(tài)的活動(dòng)需要再次展現(xiàn)給用戶的時(shí)候,觸發(fā)該方法。
3:onStart()
只要Activity從不可見(jiàn)變成可見(jiàn),就會(huì)觸發(fā)到這個(gè)方法,但被AlertDialog遮擋/顯示的情況不算在內(nèi)。
4:onResume()
當(dāng)Activity來(lái)到最上層的時(shí)候,也就是開(kāi)始與用戶直接交互時(shí),觸發(fā)這個(gè)方法。例如本來(lái)Activity被一個(gè)AlertDialog遮擋,當(dāng)這個(gè)AlertDialog消失時(shí),onResume()方法就被觸發(fā)。
5:onPause()
同onResume()的觸發(fā)條件剛好相反,如果Activity本來(lái)在最上層,當(dāng)它要讓出最上層的位置時(shí)會(huì)觸發(fā)這個(gè)方法。
onPause()和onResume()是被觸發(fā)最頻繁的兩個(gè)方法,所以在這里不應(yīng)該執(zhí)行過(guò)于消耗資源的方法。
6: onStop ()
當(dāng)一個(gè)活動(dòng)不再需要展示給用戶的時(shí)候,觸發(fā)該方法。如果內(nèi)存緊張,系統(tǒng)會(huì)直接結(jié)束這個(gè)活動(dòng),而不會(huì)觸發(fā) onStop 方法。
所以保存狀態(tài)信息是應(yīng)該在onPause時(shí)做,而不是onStop時(shí)做?;顒?dòng)如果沒(méi)有在前臺(tái)運(yùn)行,都將被停止或者Linux管理進(jìn)程為了給新的活動(dòng)預(yù)留足夠的存儲(chǔ)空間而隨時(shí)結(jié)束這些活動(dòng)。因此對(duì)于開(kāi)發(fā)者來(lái)說(shuō),在設(shè)計(jì)應(yīng)用程序的時(shí)候,必須時(shí)刻牢記這一原則。在一些情況下,onPause方法或許是活動(dòng)觸發(fā)的最后的方法,因此開(kāi)發(fā)者需要在這個(gè)時(shí)候保存需要保存的信息。
7: onDestroy ()
當(dāng)活動(dòng)銷(xiāo)毀的時(shí)候,觸發(fā)該方法。和onStop 方法一樣,如果內(nèi)存緊張,系統(tǒng)會(huì)直接結(jié)束這個(gè)活動(dòng)而不會(huì)觸發(fā)該方法。
接下來(lái)我們用代碼來(lái)實(shí)現(xiàn)具體的方法觸發(fā):
創(chuàng)建一個(gè)android項(xiàng)目,在MainActivity中進(jìn)行編輯
public class MainActivity extends Activity { // onCreate系統(tǒng)自動(dòng)初始化 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("--MainActivity--","--------onCreate- 系統(tǒng)自動(dòng)初始化---------"); } //從stop轉(zhuǎn)為激活狀態(tài)時(shí)執(zhí)行 @Override protected void onRestart() { super.onRestart(); Log.i("--MainActivity--", "------onRestart--stop轉(zhuǎn)為激活狀態(tài)時(shí)執(zhí)行----"); } //Activity開(kāi)始加載事件時(shí)執(zhí)行(新創(chuàng)建時(shí),或者重新啟動(dòng)的時(shí)候執(zhí)行!) @Override protected void onStart() { super.onStart(); Log.i("--MainActivity--", "--------onStart---開(kāi)始加載事件時(shí)執(zhí)行-----"); } //Activity恢復(fù)到激活狀態(tài)時(shí)執(zhí)行(任何一次進(jìn)入激活狀態(tài)都將執(zhí)行) @Override protected void onResume() { super.onResume(); Log.i("--MainActivity--", "----------onResume-恢復(fù)到激活狀態(tài)時(shí)執(zhí)行-------------"); } //Activity 被覆蓋的時(shí)候執(zhí)行 @Override protected void onStop() { super.onStop(); Log.i("--MainActivity--", "-------onStop ----被覆蓋的時(shí)候執(zhí)行-----------"); } //Activity 退出或者被回收時(shí)執(zhí)行,僅執(zhí)行一次 @Override protected void onDestroy() { super.onDestroy(); Log.i("--MainActivity--","---------onDestroy---退出或者被回收時(shí)執(zhí)行,僅執(zhí)行一次--------------"); } }
當(dāng)我們啟動(dòng)部署程序的時(shí)候,通過(guò)LogCat 日志來(lái)查看信息
以上就是關(guān)于掌握Activity的生命周期及各個(gè)階段觸發(fā)的事件名稱和觸發(fā)次數(shù)
第三:掌握Activity中如何在各個(gè)窗體之間傳值
如上我們知道了Activity是一個(gè)窗體的頁(yè)面顯示,既然是頁(yè)面顯示,那么我們就需要進(jìn)行顯示數(shù)據(jù)與讀取數(shù)據(jù),那么問(wèn)題來(lái)了,Activity中如何在各個(gè)窗體之間進(jìn)行傳值。
這里引入一個(gè)關(guān)鍵字: Intent:在Android中,Intent對(duì)象負(fù)責(zé)各個(gè)Activity窗口之間的切換,同時(shí)他更擔(dān)負(fù)起數(shù)據(jù)傳輸重任。
接下來(lái)我們用代碼來(lái)具體實(shí)現(xiàn)分析(采用工具Eclipse):
第一:首先我們創(chuàng)建一個(gè)名為ActivityValue 的Android項(xiàng)目 并在src 目錄下分別創(chuàng)建名為:SecondActivity JAVA普通類 ,Second_OneActivity JAVA普通類 分別繼承Activity
在目錄layout 中創(chuàng)建分別跟SecondActivity ,Second_OneActivity 相對(duì)應(yīng)的布局xml文件
名為:activity_second_one.xml
名為:activity_second.xml
接下來(lái)我們?cè)赟econdActivity.java 文件中進(jìn)行編輯:
package com.example.activityvalue; import java.util.ArrayList; import com.example.activitylife.R; import com.example.activityvalue.Second_OneActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class SecondActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //聲明Activity setContentView(R.layout.activity_second); } //傳遞一個(gè)普通值到一個(gè)窗體 public void MytestOne(View view){ System.out.println("=================傳遞一個(gè)普通值到一個(gè)窗體====================="); Intent intent = new Intent(this,Second_OneActivity.class); //窗體傳值 intent.putExtra("stuName","ABC"); intent.putExtra("stuage",20); intent.putExtra("isMerry",false); //設(shè)置數(shù)組 intent.putExtra("stuHobby",new String[]{"籃球","羽毛球","足球"}); //設(shè)置集合數(shù)值 ArrayList<String> list = new ArrayList<String>(); list.add("北京"); list.add("廣東"); list.add("美國(guó)"); //設(shè)置數(shù)值到Intent 中 intent.putStringArrayListExtra("stuCitys",list); //開(kāi)啟Activity startActivity(intent); } }
我們先在SecondActivity 文件中部署好我們需要取出的數(shù)據(jù) 不同的類型數(shù)據(jù)m,由上文可知我們是通過(guò)intent 來(lái)進(jìn)行傳值
在Second_OneActivity 進(jìn)行編輯:
package com.example.activiyvalue; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; public class Second_OneActivity extends Activity{ private TextView showText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //聲明一個(gè)布局文件 setContentView(R.layout.activity_second_one); //從Intent 中取出傳遞過(guò)來(lái)的數(shù)據(jù) Intent intent = getIntent(); //取出普通數(shù)據(jù) String name = intent.getStringExtra("stuName"); int age = intent.getIntExtra("stuAge", 0); boolean isMerry = intent.getBooleanExtra("isMerry",false); //取出數(shù)組數(shù)據(jù) String[] hobbys = intent.getStringArrayExtra("stuHobby"); String hobby = Arrays.toString(hobbys); //取出ArrayList 集合數(shù)據(jù) ArrayList<String> citys =intent.getStringArrayListExtra("stuCitys"); String city = Arrays.toString(citys.toArray()); //聲明Activity showText = (TextView) findViewById(R.id.showText); //在Activity 中動(dòng)態(tài)添加文本內(nèi)容 String str = "姓名:"+name+",年齡:"+age+"\n"+ "婚否:"+isMerry+"\n"+ "愛(ài)好:"+hobby+"\n"+ "城市:"+city; showText.setText(str); }
如果在第21 行 聲明一個(gè)布局文件 報(bào)錯(cuò)時(shí),則說(shuō)明R 文件中 沒(méi)有自動(dòng)生成句柄 我們可以這樣做
在項(xiàng)目右擊重新加載項(xiàng)目便可:
接下來(lái)我們要在項(xiàng)目目錄下的AndroidMainifest.xml 中進(jìn)行聲明Activity 類文件
在聲明的前提我們先進(jìn)行設(shè)置好string參數(shù)
接下來(lái)在AndroidMainifest.xml 開(kāi)始聲明
接下來(lái)要回到MainActivity.java 定義一個(gè)方法 用來(lái)轉(zhuǎn)跳Activity
//============================打開(kāi)一個(gè)窗體傳值的案例============================== public void setValuesMyDemo(View view){ Intent intent = new Intent(this,SecondActivityclass); //創(chuàng)建一個(gè)Activity對(duì)象 //開(kāi)始激活A(yù)ctivity狀態(tài)為start startActivity(intent); }
在activity_mainxml 布局文件中定義一個(gè)Button 按鈕
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Activity窗體傳值案例" android:onClick="setValuesMyDemo" />
按鈕綁定一個(gè)方法對(duì)應(yīng)的是MainActivity.java 中的 setValuesMyDemo 方法
setValuesMyDemo 方法中調(diào)用 下一個(gè)Activity 也就是SecondActivity.java 對(duì)應(yīng)的布局文件
那么我們就要在SecondActivity.java 對(duì)應(yīng)的布局文件activity_second.xml 中添加一個(gè)button
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="通過(guò)Intent傳遞普通數(shù)據(jù)" android:onClick="MytestOne"/>
activity_second.xml 中點(diǎn)擊事件綁定的方法是SecondActivity.java 文件中對(duì)應(yīng)的MytestOne方法:
在MytestOne方法中 調(diào)用了下一個(gè)Activity 也就是Second_OneActivity.java 我們?cè)谶@個(gè)文件中進(jìn)行讀取數(shù)據(jù) 在SecondActivity.java文件中進(jìn)行設(shè)置數(shù)值
接下來(lái)見(jiàn)證奇跡的時(shí)刻:我們運(yùn)行我們的程序,打開(kāi)我們的模擬器或者真機(jī)部署文件
點(diǎn)擊窗體中的button 進(jìn)入SecondActivity的布局文件了 (此時(shí)就進(jìn)行了頁(yè)面的跳轉(zhuǎn))
在SecondActivity頁(yè)面我們是進(jìn)行了設(shè)置數(shù)值 因此 當(dāng)再次點(diǎn)擊的時(shí)候我們?cè)赟econd_OneActivity 的布局文件就要進(jìn)行讀取數(shù)據(jù)
點(diǎn)擊 顯示跳轉(zhuǎn)如下:
總結(jié): 由上圖案例可知,Activity與Activity 之間的跳轉(zhuǎn) 跟 Activity與Activity 之間的傳值 是通過(guò)上一個(gè)Activity對(duì)下一個(gè)Activity的調(diào)用,其中intent 對(duì)象 起到的方法很重要,起著跳轉(zhuǎn)跟傳值的任務(wù)!
第三: 掌握Activity窗體狀態(tài)保存問(wèn)題
在這里如何保存當(dāng)前的窗體狀態(tài)我們通過(guò)代碼來(lái)實(shí)現(xiàn):
在我們上面的案例基礎(chǔ)上,到MainActivity.java 文件中 重寫(xiě)Activity 的兩個(gè)方法:
onRestoreInstanceState(Bundle savedInstanceState)
//========================窗體狀態(tài)保存與恢復(fù)==================================== @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); //恢復(fù)狀態(tài) if(savedInstanceState!=null){ String msg = savedInstanceState.getString("message"); //設(shè)置這個(gè)數(shù)據(jù)到需要的地方 Toast.makeText(this, "以前的消息:"+msg, 50000).show(); } }
onSaveInstanceState(Bundle outState)
//========================保存的狀態(tài)==================================== @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); //保存數(shù)據(jù) outState.putString("message", "Hello!"); Toast.makeText(this, "狀態(tài)已經(jīng)保存!", 3000).show(); }
完畢之后,我們開(kāi)始運(yùn)行程序最終結(jié)果如下:
到此這篇關(guān)于android初學(xué)者必須掌握的Activity狀態(tài)的四大知識(shí)點(diǎn)的文章就介紹到這了,更多相關(guān)activity的四種狀態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- android中Activity詳解(生命周期、以各種方式啟動(dòng)Activity、狀態(tài)保存,完全退出等)
- Android保存Activity狀態(tài)的方法
- Android學(xué)習(xí)小結(jié)之Activity保存和恢復(fù)狀態(tài)
- Android 保存Fragment 切換狀態(tài)實(shí)例代碼
- Android中用onSaveInstanceState保存Fragment狀態(tài)的方法
- 實(shí)例探究Android開(kāi)發(fā)中Fragment狀態(tài)的保存與恢復(fù)方法
- Android編程實(shí)現(xiàn)隱藏狀態(tài)欄及測(cè)試Activity是否活動(dòng)的方法
- Android中檢查、監(jiān)聽(tīng)電量和充電狀態(tài)的方法
- Android中監(jiān)聽(tīng)軟鍵盤(pán)顯示狀態(tài)實(shí)現(xiàn)代碼
- Android編程實(shí)現(xiàn)狀態(tài)保存的方法分析
相關(guān)文章
Android RecyclerView 數(shù)據(jù)綁定實(shí)例代碼
本文主要介紹Android RecyclerView 數(shù)據(jù)綁定的資料,這里詳細(xì)說(shuō)明如何實(shí)現(xiàn) Android RecyclerView的數(shù)據(jù)綁定,并附示例代碼,有需要的小伙伴可以參考下2016-09-09loadavg數(shù)據(jù)異常引發(fā)問(wèn)題起源分析
這篇文章主要為大家介紹了loadavg數(shù)據(jù)異常引發(fā)問(wèn)題起源分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11android暫停或停止其他音樂(lè)播放器的播放實(shí)現(xiàn)代碼
來(lái)自android自帶的music源碼,下面是廣播接收的代碼,通過(guò)發(fā)送廣播來(lái)控制音樂(lè)的播放,停止等2013-11-11Android實(shí)現(xiàn)仿淘寶購(gòu)物車(chē)增加和減少商品數(shù)量功能demo示例
這篇文章主要介紹了Android實(shí)現(xiàn)仿淘寶購(gòu)物車(chē)增加和減少商品數(shù)量功能,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)的淘寶購(gòu)物車(chē)商品數(shù)量變換與計(jì)算相關(guān)技巧,需要的朋友可以參考下2016-07-07android監(jiān)聽(tīng)軟鍵盤(pán)的彈出與隱藏的示例代碼
本篇文章主要介紹了android監(jiān)聽(tīng)軟鍵盤(pán)的彈出與隱藏的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02activitygroup 切換動(dòng)畫(huà)效果如何實(shí)現(xiàn)
本文將詳細(xì)介紹activitygroup 切換動(dòng)畫(huà)效果實(shí)現(xiàn)過(guò)程,需要聊解的朋友可以參考下2012-12-12