學(xué)習(xí)Android開發(fā)的小伙伴可能“四大組件”是接觸Android開發(fā)時經(jīng)常出現(xiàn)的名詞之一,四大組件的使用也是入門Android開發(fā)必備的基礎(chǔ)技能之一,這篇文章采用代碼示例的方法嘗試分析四大組件的基本使用以及各個組件的基本原理乐严。
那么,Android的四大組件究竟是哪四大組件呢?四大組件包括:Activity,Service摧扇,BroadCastReceiver,ContentProvider挚歧。本篇文章將分析Activity的生命周期及其啟動模式
生命周期:
Activity有以下幾個生命周期方法扛稽,他們分別代表什么含義,我們在每個生命周期方法中究竟應(yīng)該完成什么樣的準(zhǔn)備工作:
onCreate:表示Activity正在被創(chuàng)建滑负,這是Activity生命周期的第一個方法在张,我們可以在這個方法中做一些初始化的工作,比如setContentView去加載布局文件矮慕,綁定控件帮匾,初始化Activity所需數(shù)據(jù)等。
onStart:表示Activity正在被啟動痴鳄,這個時候Activity已經(jīng)可見瘟斜,但是還沒有顯示到前臺,無法與用戶進行交互,可以理解為界面已經(jīng)顯示了哼转,但是我們還看不到明未。
onResume:表示Activity已經(jīng)可見槽华,已經(jīng)顯示到前臺了壹蔓,并可以與用戶進行交互。
onPause:表示Activity正在停止猫态,在這個生命周期中佣蓉,我們可以做一些保存數(shù)據(jù)、停止動畫等工作亲雪,不能做比較耗時的工作勇凭。
onStop:表示Activity即將停止,我們可以做一些資源回收工作义辕,同樣不能太耗時
onDestroy:表示Activity即將背銷毀虾标,這里是Activity生命周期的最后一個方法,我們可以做一些資源釋放工作灌砖。
onRestart:表示Activity正在被重新啟動璧函,當(dāng)前Activity從不可見狀態(tài)變?yōu)榭梢姞顟B(tài),這個方法在什么時候會被調(diào)用呢基显?當(dāng)你在一個Activity中按下Home鍵切換到桌面或是打開一個新的Activity(打開新的Activity是否調(diào)用onRestart方法與Activity的啟動模式有關(guān)蘸吓,暫可不表,文章后面會有介紹)時撩幽,系統(tǒng)會調(diào)用Activity的onPause库继、onStop生命周期方法,當(dāng)你回到這個Activity時窜醉,如果這個Activity沒有被系統(tǒng)回收宪萄,就會調(diào)用onRestart方法
Activity的生命周期如下圖所示:
下面我會用代碼說明Activity各種情境下的生命周期:
以下是MainActivity的代碼
package com.danc.dancactivitystudy;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivityextends AppCompatActivity {
private static final StringTAG ="danKeeper";
private ButtonmBtnJump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "MainActivity onCreate() be called");
setContentView(R.layout.activity_main);
mBtnJump = findViewById(R.id.btn_jump);
mBtnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
@Override
protected void onStart() {
Log.d(TAG, "MainActivity onStart() be called");
super.onStart();
}
@Override
protected void onResume() {
Log.d(TAG, "MainActivity onResume() be called");
super.onResume();
}
@Override
protected void onPause() {
Log.d(TAG, "MainActivity onPause() be called");
super.onPause();
}
@Override
protected void onStop() {
Log.d(TAG, "MainActivity onStop() be called");
super.onStop();
}
@Override
protected void onDestroy() {
Log.d(TAG, "MainActivity onDestroy() be called");
super.onDestroy();
}
@Override
protected void onRestart() {
Log.d(TAG, "MainActivity onRestart() be called");
super.onRestart();
}
}
以下是SecondActivity的代碼
package com.danc.dancactivitystudy;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class SecondActivityextends AppCompatActivity {
private static final StringTAG ="danKeeper";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "SecondActivity onCreate() be called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
@Override
protected void onStart() {
Log.d(TAG, "SecondActivity onStart() be called");
super.onStart();
}
@Override
protected void onResume() {
Log.d(TAG, "SecondActivity onResume() be called");
super.onResume();
}
@Override
protected void onPause() {
Log.d(TAG, "SecondActivity onPause() be called");
super.onPause();
}
@Override
protected void onStop() {
Log.d(TAG, "SecondActivity onStop() be called");
super.onStop();
}
@Override
protected void onDestroy() {
Log.d(TAG, "SecondActivity onDestroy() be called");
super.onDestroy();
}
@Override
protected void onRestart() {
Log.d(TAG, "SecondActivity onRestart() be called");
super.onRestart();
}
}
(一)啟動MainActivity
日志如下
MainActivity onCreate() be called
MainActivity onStart() be called
MainActivity onResume() be called
說明這個情況下MainActivity的生命周期是:
onCreate > onStart > onResume
(二)跳轉(zhuǎn)至SecondActivity
日志如下
MainActivity onCreate() be called
MainActivity onStart() be called
MainActivity onResume() be called
MainActivity onPause() be called
SecondActivity onCreate() be called
SecondActivity onStart() be called
SecondActivity onResume() be called
MainActivity onStop() be called
說明這個情況下的生命周期是:
onCreate > onStart > onResume > onPause > SecondActivity onCreate > SecondActivity onStart > SecondActivity onResume > onStop
也就是說頁面跳轉(zhuǎn)時是先執(zhí)行MainActivity的onPause生命周期,然后開始執(zhí)行SecondActivity的生命周期榨惰,當(dāng)SecondActivity頁面可見之后拜英,MainActivity執(zhí)行onStop生命周期
(三)返回鍵返回第一個Activity
日志如下
SecondActivity onPause() be called
MainActivity onRestart() be called
MainActivity onStart() be called
MainActivity onResume() be called
SecondActivity onStop() be called
SecondActivity onDestroy() be called
說明這個情況下的生命周期是:
SecondActivity onPause > onRestart > onStart > onResume > SecondActivity onStop > SecondActivity onDestroy
這里我們可以看到走到了onRestart生命周期,這是由于跳轉(zhuǎn)到SecondActivity時MainActivity并沒有被銷毀读串,也就是沒有走到onDestroy生命周期聊记,所以當(dāng)返回上一頁面也就是返回MainActivity時會走到MainActivity的onRestart生命周期。這里會有一個特殊情況恢暖,如果SecondActivity采用了透明主題排监,跳轉(zhuǎn)至SecondActivity時并不會走到onStop生命周期,同樣的杰捂,返回時也不會走到onStart生命周期舆床,生命周期變?yōu)椋?br> onCreate > onStart > onResume > onPause > SecondActivity onCreate > SecondActivity onStart > SecondActivity onResume > SecondActivity onPause > onResume > SecondActivity onStop > SecondActivity onDestroy
啟動模式:
我們知道,默認(rèn)情況下,啟動同一個Activity時系統(tǒng)會創(chuàng)建多個實例并把它們放到任務(wù)棧中挨队,當(dāng)我們按下返回鍵時谷暮,會一一展示我們剛剛打開的Activity,每按一次返回鍵棧頂?shù)腁ctivity就會出棧盛垦,直到検遥空為止。那么問題來了腾夯,為什么創(chuàng)建一個Activity時就要將一個新的實例入棧呢颊埃?為什么不從棧中看看是否有這個Activity的實例呢?Android設(shè)計的時候就提供了四種Activity的啟動模式來供開發(fā)者選擇蝶俱,每種啟動模式都有他們的特性以及使用場景班利。
standard:
標(biāo)準(zhǔn)模式,這也是系統(tǒng)的默認(rèn)啟動模式榨呆。每次新啟動一個Activity時都會實例化該Activity對象罗标,不管任務(wù)棧中是否已經(jīng)有這個Activity的實例。
singleTop:
棧頂復(fù)用模式积蜻。新啟動一個Activity時會檢查任務(wù)棧頂是否是該Activity的實例闯割,如果是,就不會重新創(chuàng)建這個Activity浅侨,同時onIntent方法會被回調(diào)纽谒,如果不是,就會添加一個新的該Activity實例到棧頂如输。舉個例子鼓黔,假如現(xiàn)在任務(wù)棧從棧頂?shù)綏5追謩e為ABCD四個Activity,如果這時跳轉(zhuǎn)至A不见,如果A的啟動模式為singleTop澳化,那么任務(wù)棧的結(jié)構(gòu)就是ABCD,如果是stantard稳吮,那么任務(wù)棧的結(jié)構(gòu)就是AABCD缎谷。
singleTask;
棧內(nèi)復(fù)用模式。這是一種單實例模式灶似,只要Actiivty在一個任務(wù)棧存在列林,那么啟動這個Activity都不會創(chuàng)建新的實例,而是將任務(wù)棧中Activity調(diào)到棧頂酪惭,調(diào)用它的onNewIntent方法希痴,如果任務(wù)棧中不存在這個Activity的實例,則會創(chuàng)建Activity的實例并入棧春感。比如任務(wù)棧S1中有ABC三個Activity砌创,此時我要進入D虏缸,如果D需要的任務(wù)棧是S2,那么系統(tǒng)會先創(chuàng)建S2任務(wù)棧嫩实,并將D入棧刽辙,棧結(jié)構(gòu)為S1:ABC,S2:D甲献,如果D需要的任務(wù)棧就是S1宰缤,那么系統(tǒng)會創(chuàng)建一個D的實例并入棧,那么此時S1中就是DABC竟纳,此時我們在跳轉(zhuǎn)到B中撵溃,那么S1任務(wù)棧中就會變?yōu)锽C。
singleInstance:
singleInstance除了具有singleTask所有特性之外锥累,singleInstance啟動模式下的Activity只 能單獨位于一個任務(wù)棧中,換句話說集歇,當(dāng)要啟動A時桶略,只要所有任務(wù)棧中沒有A的實例,系統(tǒng)就會為A創(chuàng)建一個任務(wù)棧诲宇,這個任務(wù)棧中只會存在A际歼,后續(xù)要進入A,都不會創(chuàng)建新的實例姑蓝,直到系統(tǒng)將這個特殊的任務(wù)椂煨模回收。