Android四大組件的生命周期、使用方法、ANR時間及四大啟動模式的生命周期與使用場景
一、Android四大組件的生命周期、使用方法及ANR
1. Activity
Activity 是應(yīng)用中最重要的組件之一,通常負(fù)責(zé)顯示用戶界面。每個Activity都對應(yīng)著一個生命周期,開發(fā)者可以在生命周期的不同階段執(zhí)行相關(guān)操作,如初始化、釋放資源等。
Activity的生命周期:
- onCreate():Activity第一次創(chuàng)建時調(diào)用。在此方法中通常進(jìn)行UI布局的初始化、數(shù)據(jù)的設(shè)置等。
- onStart():當(dāng)Activity對用戶可見時調(diào)用,但此時它并沒有獲得焦點。
- onResume():Activity獲得焦點并開始與用戶交互時調(diào)用,此時Activity處于前臺。
- onPause():當(dāng)系統(tǒng)正在啟動或恢復(fù)另一個Activity時,當(dāng)前Activity失去焦點時調(diào)用。此時可以保存臨時數(shù)據(jù)、釋放資源等。
- onStop():當(dāng)Activity不再對用戶可見時調(diào)用。此時Activity完全處于后臺,可以進(jìn)行資源的釋放工作。
- onRestart():當(dāng)Activity從停止?fàn)顟B(tài)恢復(fù)時調(diào)用。通常用于恢復(fù)UI等。
- onDestroy():當(dāng)Activity銷毀時調(diào)用。此時應(yīng)釋放資源,清理工作。
使用方法:
-
啟動Activity:可以通過
startActivity()啟動另一個Activity,通常還會攜帶數(shù)據(jù):Intent intent = new Intent(this, TargetActivity.class); intent.putExtra("key", "value"); startActivity(intent); -
返回數(shù)據(jù):可以通過
setResult()向調(diào)用的Activity返回結(jié)果,并通過onActivityResult()接收返回的數(shù)據(jù)。
ANR時間限制:
- ANR(Application Not Responding) 是當(dāng)應(yīng)用在主線程上執(zhí)行耗時操作(如網(wǎng)絡(luò)請求、數(shù)據(jù)庫操作、界面更新等)超過一定時間,Android系統(tǒng)會判定應(yīng)用無響應(yīng),并彈出ANR對話框。通常,ANR的時間限制為 5秒(針對輸入事件)和 10秒(針對廣播接收器)。
-
避免ANR:長時間的操作應(yīng)該放到子線程中,避免阻塞主線程??梢允褂?code>AsyncTask、
HandlerThread、IntentService等來進(jìn)行后臺操作。
2. Service
Service 是用于執(zhí)行長時間運行的后臺任務(wù)的組件,它沒有用戶界面,通常用于后臺處理任務(wù),如播放音樂、下載文件等。
Service的生命周期:
- onCreate():Service第一次創(chuàng)建時調(diào)用,通常在此方法中初始化資源。
-
onStartCommand():每次調(diào)用
startService()時,都會調(diào)用此方法。在此方法中執(zhí)行后臺任務(wù)。返回值決定Service如何重新啟動:-
START_STICKY:Service會在被殺死后重新啟動。 -
START_NOT_STICKY:Service被殺死后不會重新啟動。 -
START_REDELIVER_INTENT:Service被殺死后會重新啟動,并傳遞最新的Intent。
-
-
onBind():當(dāng)
bindService()被調(diào)用時,執(zhí)行此方法。返回一個IBinder對象,允許組件與Service進(jìn)行通信。 - onUnbind():當(dāng)所有客戶端都解綁時調(diào)用。
- onDestroy():Service銷毀時調(diào)用,用于清理資源和停止后臺任務(wù)。
使用方法:
-
啟動Service:
Intent intent = new Intent(this, MyService.class); startService(intent); -
綁定Service:
Intent intent = new Intent(this, MyService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE);
ANR時間限制:
- ANR:在Service中進(jìn)行網(wǎng)絡(luò)請求、數(shù)據(jù)庫操作等耗時操作時,如果沒有在子線程中執(zhí)行超過20S,就可能導(dǎo)致ANR。
-
避免ANR:確保長時間運行的任務(wù)不會阻塞主線程,可以通過使用
AsyncTask、ExecutorService等將任務(wù)放到子線程中。
3. BroadcastReceiver
BroadcastReceiver 用于接收廣播并響應(yīng)它。廣播可以是系統(tǒng)廣播(例如電池電量變化、網(wǎng)絡(luò)狀態(tài)變化)或應(yīng)用自定義廣播。
BroadcastReceiver的生命周期:
-
onReceive():每當(dāng)廣播被接收時,
onReceive()方法被調(diào)用。該方法在調(diào)用完成后立即結(jié)束,BroadcastReceiver會被銷毀。因此,onReceive()中不應(yīng)執(zhí)行耗時操作。
使用方法:
-
靜態(tài)注冊:通過在
AndroidManifest.xml中聲明廣播接收器。<receiver android:name=".MyReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> -
動態(tài)注冊:通過
registerReceiver()方法注冊,在不需要時應(yīng)調(diào)用unregisterReceiver()注銷。IntentFilter filter = new IntentFilter("android.intent.action.BOOT_COMPLETED"); registerReceiver(new MyReceiver(), filter);
ANR時間限制:
-
ANR:廣播接收器的
onReceive()方法如果執(zhí)行時間超過 10秒,會導(dǎo)致ANR。因此,廣播接收器中的代碼應(yīng)盡量避免耗時操作。 -
避免ANR:對于耗時操作,應(yīng)該通過
Handler、AsyncTask等異步方式在后臺執(zhí)行,避免阻塞onReceive()。
4. ContentProvider
ContentProvider 是用于不同應(yīng)用之間共享數(shù)據(jù)的組件。通過ContentResolver,其他應(yīng)用可以訪問提供的數(shù)據(jù)。
ContentProvider的生命周期:
- ContentProvider的生命周期由系統(tǒng)管理,通常在第一次訪問時創(chuàng)建,并在不再使用時銷毀。
使用方法:
-
查詢數(shù)據(jù):
Uri uri = Uri.parse("content://com.example.provider/data"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); -
插入數(shù)據(jù):
ContentValues values = new ContentValues(); values.put("name", "John"); Uri uri = getContentResolver().insert(uri, values);
ANR時間限制:
- ANR:ContentProvider的查詢、插入、更新等操作如果執(zhí)行過慢,可能會導(dǎo)致ANR。特別是在進(jìn)行數(shù)據(jù)庫操作時,如果查詢操作沒有加速,就可能導(dǎo)致ANR。
- 避免ANR:對于復(fù)雜的數(shù)據(jù)庫查詢或大規(guī)模數(shù)據(jù)的操作,建議使用異步查詢或分批操作。
二、四大啟動模式的生命周期與使用場景
Android提供了四種啟動模式(Standard、SingleTop、SingleTask、SingleInstance),每種模式都會影響Activity的生命周期、任務(wù)棧以及啟動時的行為。合理選擇啟動模式,可以幫助開發(fā)者避免冗余實例,提高內(nèi)存利用效率和用戶體驗。
1. Standard(標(biāo)準(zhǔn)模式)
在標(biāo)準(zhǔn)模式下,每次調(diào)用startActivity()都會創(chuàng)建新的Activity實例,新的實例會被添加到任務(wù)棧的頂部。
生命周期:
- 每次調(diào)用
startActivity()都會觸發(fā)onCreate()、onStart()、onResume()等方法。 - 每個Activity都會創(chuàng)建一個新的實例,并且在任務(wù)棧中有獨立的生命周期。
使用場景:
適用于每次需要創(chuàng)建一個新的Activity實例的場景,如新聞頁面、列表頁等。
注意點:
- 可能導(dǎo)致內(nèi)存占用過高,特別是在頻繁切換界面時。
- 如果沒有合理管理Activity的堆棧,可能會導(dǎo)致棧中堆積大量實例。
2. SingleTop(單例模式)
當(dāng)目標(biāo)Activity已經(jīng)位于棧頂時,系統(tǒng)不會創(chuàng)建新的實例,而是復(fù)用棧頂?shù)腁ctivity。如果目標(biāo)Activity不在棧頂,則會創(chuàng)建新的實例。
生命周期:
- 如果目標(biāo)Activity在棧頂,
onNewIntent()方法會被調(diào)用,而不是onCreate()。 - 如果目標(biāo)Activity不在棧頂,創(chuàng)建新的實例。
使用場景:
適用于避免棧頂重復(fù)創(chuàng)建實例的場景,例如聊天界面、通知界面等。
注意點:
- 如果目標(biāo)Activity已經(jīng)在棧頂,
onCreate()不會被調(diào)用,只有onNewIntent()會被調(diào)用。 -
onNewIntent()方法中應(yīng)該處理新的Intent數(shù)據(jù)。
3. SingleTask(單任務(wù)模式)
當(dāng)啟動一個SingleTask模式的Activity時,系統(tǒng)會查找該Activity是否已存在于任務(wù)棧中。如果存在,則會將
該Activity及其上面的Activity從棧中移除,并將目標(biāo)Activity置于棧頂。
生命周期:
- 如果目標(biāo)Activity已存在,會調(diào)用
onNewIntent(),并將目標(biāo)Activity帶到前臺。 - 如果目標(biāo)Activity不存在,系統(tǒng)會創(chuàng)建新的實例。
使用場景:
適用于那些只需要一個實例的Activity,如登錄頁面、主頁面等。
注意點:
- 由于每次啟動都會清除棧中上面的Activity,使用時需要謹(jǐn)慎處理棧內(nèi)的狀態(tài)。
4. SingleInstance(單實例模式)
SingleInstance模式下,Activity被放置在一個獨立的任務(wù)棧中,且該棧中只會有一個實例。其他任何啟動該Activity的請求都會復(fù)用該實例。
生命周期:
- 只有一個實例,所有啟動請求都會復(fù)用該實例。
使用場景:
適用于只有一個實例的全局Activity,例如某些全局控制界面。
注意點:
-
SingleInstance模式的Activity被放置在獨立的任務(wù)棧中,和其他任務(wù)棧的Activity不會在同一棧中。使用時要注意棧之間的跳轉(zhuǎn)與狀態(tài)管理。
總結(jié)
理解Android四大組件的生命周期、使用方法以及ANR的時間限制,可以幫助開發(fā)者避免常見的性能問題和內(nèi)存泄漏。合理選擇四大啟動模式,不僅能夠優(yōu)化內(nèi)存管理,還能提升用戶體驗。在應(yīng)用設(shè)計中,開發(fā)者需要根據(jù)實際需求來選擇合適的啟動模式和組件使用方式,以實現(xiàn)高效的任務(wù)管理和流暢的用戶交互。