Android基礎(chǔ)06-Activity及其生命周期

一、Activity初步認(rèn)識(shí):【創(chuàng)建、配置、啟動(dòng)Activity】

(一)、創(chuàng)建Activity:

創(chuàng)建Activity:繼承于Activity或其子類(lèi),重寫(xiě)onCreate()方法。

(二)、Activity的注冊(cè)配置:

作為四大組件之一的Activity,必須要在AndroidManifest清單文件中進(jìn)行注冊(cè)。如果沒(méi)有配置,而又在程序中啟動(dòng)了該Activity,將拋出異常(ActivityNotFoundException)。

注冊(cè)配置的核心代碼:

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme">

android:name=".MainActivity"

android:label="@string/app_name">

android:name=".HeadpicActivity"

android:label="@string/title_activity_headpic">

【附加思考】:

當(dāng)在AndroidManifest清單文件中,設(shè)置多個(gè)頁(yè)面都是默認(rèn)啟動(dòng)頁(yè),會(huì)報(bào)錯(cuò)嗎?如果不 報(bào)錯(cuò),到底是執(zhí)行哪個(gè)頁(yè)面呢?

當(dāng)在AndroidManifest清單文件中,如果不設(shè)置默認(rèn)啟動(dòng)頁(yè),會(huì)報(bào)錯(cuò)嗎?

(三)、啟動(dòng)Activity:

在Android應(yīng)用里各組件之間通信使用Intent。一個(gè)Activity通過(guò)Intent來(lái)表達(dá)自己的“意圖”。

常用有兩種方式:

Intent intent = new Intent(MainActivity.this , NextActivity.class);

Intent intent = new Intent();

?intent.setClass(MainActivity.this , NextActivity.class);

常用啟動(dòng)方式有兩種:

startActivity();

startActivityForResult();

(四)、Activity之間交換數(shù)據(jù):

第一種方式:

甲頁(yè)面利用intent對(duì)象的putExtra()方法傳值,乙頁(yè)面利用getStringExtra()、getIntExtra()等系列方法來(lái)一一接收值;

第二種方式:【常用】

甲頁(yè)面利用bundle對(duì)象來(lái)保存所有需要傳遞的數(shù)值,通過(guò)intent的putExtras()方法傳值,乙頁(yè)面利用intent對(duì)象的getExtras()方法返回bundle對(duì)象,將所有接收的數(shù)據(jù)放在bundle對(duì)象中,利用bundle的get系列方法一一去除數(shù)據(jù)。

????? ? 【備注:】如果甲頁(yè)面使用putExtras()方法傳值,則乙頁(yè)面使用getExtras()接收值。如果甲頁(yè)面使用putExtra()方法傳值,則乙頁(yè)面要使用getBundleExtra()方法接收值。

Activity之間是否可以傳遞對(duì)象呢?【掌握Serializable的用法】

Serializable的用法

Parcelable的用法

1、傳遞一般數(shù)據(jù)的核心代碼:

(1)、MainActivity頁(yè)面:

publicvoidclickButton(View view) {

switch(view.getId()) {

caseR.id.button_main_tonext:

Intent intent =newIntent(MainActivity.this, NextActivity.class);

Bundle bundle =newBundle();

bundle.putString("myname", "hehaitao");

bundle.putInt("age", 16);

intent.putExtras(bundle);

startActivity(intent);

break;

}

}

(2)、NextActivity頁(yè)面:

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_next);

// 接收第一個(gè)頁(yè)面的傳值

Intent intent = getIntent();

Bundle bundle = intent.getExtras();

String name = bundle.getString("myname");

intage = bundle.getInt("age");

this.setTitle(name + ":" + age);

}

2、傳遞對(duì)象數(shù)據(jù)的核心代碼:

(1)、Person對(duì)象核心代碼:

publicclassPersonimplementsSerializable {

privateString userName;

privateintage;

privateintsex;

privateList infoList;

publicList getInfoList() {

returninfoList;

}

publicvoidsetInfoList(List infoList) {

this.infoList = infoList;

}

publicString getUserName() {

returnuserName;

}

publicvoidsetUserName(String userName) {

this.userName = userName;

}

publicintgetAge() {

returnage;

}

publicvoidsetAge(intage) {

this.age = age;

}

publicintgetSex() {

returnsex;

}

publicvoidsetSex(int

this.sex = sex;

}

}

(2)、MainActivity頁(yè)面:

publicclassMainActivityextendsActivity {

privatePerson person =null;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

List list =newArrayList();

list.add("one");

list.add("two");

list.add("three");

person =newPerson();

person.setUserName("wangxiangjun");

person.setAge(40);

person.setSex(1);

person.setInfoList(list);

}

publicvoidclickButton(View view) {

switch(view.getId()) {

caseR.id.button_main_submit:

Intent intent =newIntent(MainActivity.this,

ReceiverActivity.class);

Bundle bundle =newBundle();

bundle.putSerializable("person", person);

intent.putExtras(bundle);

startActivity(intent);

break;

}

}

@Override

publicbooleanonCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

returntrue;

}

}

(3)、MainActivity頁(yè)面:

publicclassReceiverActivityextendsActivity {

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_receiver);

Intent intent = getIntent();

Bundle bundle = intent.getExtras();

// 接收Serializable對(duì)象

Person data = (Person) bundle.getSerializable("person");

setTitle(data.getUserName() + ":" + data.getAge() + ":"

+ data.getInfoList());

}

@Override

publicbooleanonCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.receiver, menu);

returntrue;

}

}


二、Activity——調(diào)用另一個(gè)Activity并返回結(jié)果:

(一)、概念:

甲頁(yè)面調(diào)用乙頁(yè)面,當(dāng)用戶(hù)在乙頁(yè)面完成任務(wù)后,程序自動(dòng)返回到甲頁(yè)面,而甲頁(yè)面必須能夠獲取到用戶(hù)在完成乙頁(yè)面后傳遞的數(shù)據(jù)結(jié)果。

(二)、做法:

與普通的頁(yè)面交換數(shù)據(jù)不同的是,要使用startActivityForResult()方法來(lái)啟動(dòng)另一個(gè)Activity。

(三)、示例代碼:

1、MainActivity頁(yè)面:

publicclassMainActivityextendsActivity {

privateImageView imageView_main_headpic;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

imageView_main_headpic = (ImageView) findViewById(R.id.imageView_main_headpic);

}

@Override

publicbooleanonCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

returntrue;

}

publicvoidclickButton(View view) {

switch(view.getId()) {

caseR.id.button_main_selectpic:

Intent intent =newIntent(MainActivity.this, HeadpicActivity.class);

startActivityForResult(intent, 0);

break;

}

}

@Override

protectedvoidonActivityResult(intrequestCode,intresultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if(requestCode == 0 && resultCode == 1) {

Bundle bundle = data.getExtras();

intimgid = bundle.getInt("imgId");

imageView_main_headpic.setImageResource(imgid);

}

}

}

2、NextActivity頁(yè)面:

publicclassHeadpicActivityextendsActivity {

privateGridView gridView_headpic_show;

// 定義數(shù)據(jù)源

privateint[] imgIds =newint[] { R.drawable.img01, R.drawable.img02,

R.drawable.img03, R.drawable.img04, R.drawable.img05,

R.drawable.img06, R.drawable.img07, R.drawable.img08,

R.drawable.img09};

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_headpic);

gridView_headpic_show = (GridView) findViewById(R.id.gridView_headpic_show);

List> list =newArrayList>();

for(inti = 0; i < imgIds.length; i++) {

Map map =newHashMap();

map.put("headpic", imgIds[i]);

map.put("picname", "頭像—" + i);

list.add(map);

}

SimpleAdapter adapter =newSimpleAdapter(this, list,

R.layout.item_gridview_headpic,newString[] { "picname",

"headpic" },newint[] {

R.id.text_item_gridview_picname,

R.id.imageView_item_gridview_headpic});

gridView_headpic_show.setAdapter(adapter);

gridView_headpic_show.setOnItemClickListener(newOnItemClickListener() {

@Override

publicvoidonItemClick(AdapterView parent, View view,

intposition,longid) {

Intent intent = getIntent();

Bundle bundle =newBundle();

bundle.putInt("imgId", imgIds[position]);

intent.putExtras(bundle);

setResult(1, intent);

finish();

}

});

}

@Override

publicbooleanonCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.headpic, menu);

returntrue;

}

}


三、Activity生命周期:

(一)、課堂引入:人的生命周期是怎么樣的?

胎兒

嬰兒

兒童、少年、青年、中年

突發(fā)變故

老年

死亡

(二)、Activity生命周期:

1、Activity一生中有七種不同的狀態(tài)。

onCreate()

onStart()

onResume()

onPause()

onStop()

onRestart()

onDestroy()

【備注:】

A、七個(gè)生命周期組合:

onCreate、onStart、onResume:?jiǎn)?dòng)應(yīng)用程序

onPause、onStop:失去焦點(diǎn)

onRestart、onStart、onResume:重新獲得焦點(diǎn)

onPause、onStop、onDestroy?:退出應(yīng)用程序

B、七個(gè)生命周期按階段劃分:

onCreate() --- onDestroy() ? ? ? ? ? ?完整生命周期 ? ?The entire lifetime

onStart() --- onStop() ? ? ? ? ? ? ? ? ? ?可見(jiàn)生命周期 ? ??The visible lifetime:

onResume() --- onPause() ? ? ? ? ? ?前沿生命周期(焦點(diǎn)生命周期) ? ?The foreground lifetime:

2、定義生命周期的作用:

①當(dāng)用戶(hù)接一個(gè)電話(huà)或切換到另一個(gè)程序不會(huì)崩潰

②當(dāng)用戶(hù)后臺(tái)運(yùn)行程序時(shí)不會(huì)銷(xiāo)毀有價(jià)值的系統(tǒng)資源

③當(dāng)用戶(hù)離開(kāi)再返回你的應(yīng)用時(shí)不會(huì)丟失用戶(hù)的進(jìn)程

④當(dāng)手機(jī)屏幕進(jìn)行橫豎屏切換的時(shí)候不會(huì)崩潰或者丟掉用戶(hù)的進(jìn)程

3、生命周期的金字塔圖


(三)、實(shí)例代碼操作:

模仿以下操作,觀察輸出日志,找尋生命周期方法依次回調(diào)的規(guī)律:

打開(kāi)主界面,后退鍵退出

打開(kāi)主界面,進(jìn)入第二個(gè)頁(yè)面

打開(kāi)主界面,模擬電話(huà)進(jìn)入及掛機(jī),再次顯示主界面

打開(kāi)主界面,HOME鍵退出

打開(kāi)主界面,HOME鍵退出,再次啟動(dòng)app

打開(kāi)主界面,點(diǎn)擊該界面中捆綁退出事件的按鈕后退出

打開(kāi)主界面,切換橫屏豎屏。

生命周期執(zhí)行的順序:

04-23 03:51:29.750: I/MainActivity(741): ==MainActivity onCreate執(zhí)行了

04-23 03:51:29.759: I/MainActivity(741): ==MainActivity onStart執(zhí)行了

04-23 03:51:29.759: I/MainActivity(741): ==MainActivity onResume執(zhí)行了

04-23 03:52:04.780: I/MainActivity(741): ==MainActivity onPause執(zhí)行了

04-23 03:52:04.791: I/MainActivity(741): ==MainActivity onStop執(zhí)行了

04-23 03:52:04.791: I/MainActivity(741): ==MainActivity onDestroy執(zhí)行了

04-23 03:52:05.200: I/MainActivity(741): ==MainActivity onCreate執(zhí)行了

04-23 03:52:05.209: I/MainActivity(741): ==MainActivity onStart執(zhí)行了

04-23 03:52:05.329: I/MainActivity(741): ==MainActivity onResume執(zhí)行了

【思考:】

兩個(gè)Activity頁(yè)面,點(diǎn)第一個(gè)中的按鈕,進(jìn)入第二個(gè)頁(yè)面,此時(shí)點(diǎn)HOME退出程序。隨后再次啟動(dòng)app,依次會(huì)執(zhí)行哪些生命周期的回調(diào)方法。如果再點(diǎn)擊返回,繼續(xù)會(huì)執(zhí)行哪些生命周期的回調(diào)方法?

請(qǐng)自己將依次調(diào)用的方法寫(xiě)在下面,不要借助機(jī)器調(diào)試。

【橫豎屏切換時(shí)的生命周期問(wèn)題的解決】

(一)、android:configChanges屬性

對(duì)android:configChanges屬性,一般認(rèn)為有以下幾點(diǎn):

1、不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次,切豎屏?xí)r會(huì)執(zhí)行兩次

2、設(shè)置Activity的android:configChanges="orientation"時(shí),切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫、豎屏?xí)r只會(huì)執(zhí)行一次

3、設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時(shí),切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法

但是,自從Android 3.2(API 13),在設(shè)置Activity的android:configChanges="orientation|keyboardHidden"后,還是一樣 會(huì)重新調(diào)用各個(gè)生命周期的。因?yàn)閟creen size也開(kāi)始跟著設(shè)備的橫豎切換而改變。所以,在AndroidManifest.xml里設(shè)置的MiniSdkVersion和 TargetSdkVersion屬性大于等于13的情況下,如果你想阻止程序在運(yùn)行時(shí)重新加載Activity,除了設(shè)置"orientation", 你還必須設(shè)置"ScreenSize"。

解決方法:

AndroidManifest.xml中設(shè)置android:configChanges="orientation|screenSize“

(四)、Activty生命周期的應(yīng)用場(chǎng)景

游戲過(guò)程中電話(huà)進(jìn)入

Android音樂(lè)播放器

1、模擬Android音樂(lè)播放器,練習(xí)Activity生命周期的示例代碼:

【目的:練習(xí)Activity生命周期,要明白不是所有的代碼都寫(xiě)在onCreate()方法中,而是需要根據(jù)需求寫(xiě)在生命周期的不同的回調(diào)方法中。】

publicclassMainActivityextendsActivity {

privatestaticfinalStringTAG= "MainActivity";

privatestaticinti= 0;

privateButton button_main_play;

privateTimer timer =null;

privatebooleanflag =false;// 設(shè)置flag標(biāo)記位的目的是避免程序一開(kāi)啟就執(zhí)行,而是等點(diǎn)擊了按鈕后才開(kāi)始。

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

button_main_play = (Button) findViewById(R.id.button_main_play);

button_main_play.setOnClickListener(newOnClickListener() {

@Override

publicvoidonClick(View v) {

// 點(diǎn)擊按鈕后執(zhí)行播放

playMusic();

// 設(shè)置flag標(biāo)記位的目的是避免程序一開(kāi)啟就執(zhí)行。現(xiàn)在點(diǎn)擊了按鈕,允許程序在再次執(zhí)行的時(shí)候自動(dòng)執(zhí)行。

flag =true;

}

});

}

@Override

protectedvoidonStart() {

super.onStart();

}

@Override

protectedvoidonResume() {

super.onResume();

// 默認(rèn)flag為false,不允許自動(dòng)執(zhí)行,而是當(dāng)點(diǎn)擊了播放后才允許執(zhí)行。

if(flag) {

playMusic();

}

}

@Override

protectedvoidonPause() {

super.onPause();

// 當(dāng)有電話(huà)進(jìn)入,會(huì)回調(diào)onPause()方法,這個(gè)時(shí)候要讓播放器停止。

// 定時(shí)器timer對(duì)象的cancel()方法能取消定時(shí)器。

timer.cancel();

}

@Override

protectedvoidonStop() {

super.onStop();

}

@Override

protectedvoidonRestart() {

super.onRestart();

}

@Override

protectedvoidonDestroy() {

super.onDestroy();

// 如果希望程序退出后,下次運(yùn)行從頭開(kāi)始播放,可以將進(jìn)度初始化為0.

// 如果點(diǎn)HOME退出,程序沒(méi)有完全退出,下次播放應(yīng)該從上次的進(jìn)度繼續(xù)執(zhí)行。所以不應(yīng)該初始化。

// 所以將初始化寫(xiě)在onDestroy(),而不寫(xiě)在onStop()中。(因?yàn)辄c(diǎn)HOME退出不會(huì)回調(diào)onDestroy()方法。)

i= 0;

}

@Override

publicbooleanonCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);

returntrue;

}

publicvoidplayMusic() {

// 用定時(shí)器輸出數(shù)字來(lái)模擬播放器播放的效果

timer =newTimer();

// 定時(shí)器timer對(duì)象的sechedule()方法有三個(gè)參數(shù),第一個(gè)表示定時(shí)執(zhí)行的任務(wù),第二個(gè)參數(shù)表示延遲時(shí)間,第三個(gè)參數(shù)表示間隔的時(shí)間

timer.schedule(newTimerTask() {

@Override

publicvoidrun() {

Log.i(TAG, "==i=" +i);

i++;

}

}, 0, 1000);

}

}


四、任務(wù)與回退棧:

(一)、任務(wù)Task:

1、概念:

一個(gè)任務(wù)(task)就是在執(zhí)行某項(xiàng)工作時(shí)與用戶(hù)進(jìn)行交互的Activity的集合。這些Activity按照被打開(kāi)的順序依次被安排在一個(gè)堆棧中(回退棧)。

2、主屏頁(yè)面:

設(shè)備的主屏是大多數(shù)任務(wù)的啟動(dòng)位置,當(dāng)用戶(hù)觸摸一個(gè)應(yīng)用程序啟動(dòng)器圖標(biāo)(或者app快捷圖標(biāo)),應(yīng)用程序的任務(wù)就會(huì)在前臺(tái)顯示。如果相關(guān)應(yīng)用程序的任務(wù)不存在,那么就會(huì)有一個(gè)新的任務(wù)被創(chuàng)建,并且應(yīng)用程序打開(kāi)的“主”Activity會(huì)作為任務(wù)中的根Activity。

(二)、回退棧:

1、概念:

在當(dāng)前的Activity啟動(dòng)了另一個(gè)Activity時(shí),這個(gè)新的Activity被放到了堆棧的頂部,并且?guī)в薪裹c(diǎn)。前一個(gè)Activity并沒(méi)有消失,而是保存在回退棧中,此時(shí)它處于停止?fàn)顟B(tài)。

當(dāng)用戶(hù)按下回退按鈕時(shí),當(dāng)前的Activity會(huì)被從回退棧的頂部彈出(這個(gè)Activity被銷(xiāo)毀),而前一個(gè)Activity被恢復(fù)。堆棧中的Activity不會(huì)被重新排列。因此,回退棧的操作跟后進(jìn)先出的對(duì)象結(jié)構(gòu)是一樣的。

在用戶(hù)按下回退按鈕時(shí),當(dāng)前Activity被銷(xiāo)毀,并且前一個(gè)Activity被恢復(fù)。如果用戶(hù)繼續(xù)按回退按鈕,那么回退棧中的每個(gè)Activity會(huì)被依次彈出,前一個(gè)Activity會(huì)被顯示,直到用戶(hù)返回主屏(或者返回到任務(wù)開(kāi)始時(shí)運(yùn)行的那個(gè)Activity)。當(dāng)所有的Activity從回退棧中被刪除時(shí),這個(gè)任務(wù)就不再存在了。

圖1:用一個(gè)時(shí)間表顯示了當(dāng)前回退堆棧中的Activity之間在每個(gè)時(shí)間點(diǎn)的處理過(guò)程


2、多個(gè)任務(wù):


圖2. 兩個(gè)任務(wù):任務(wù)B在前臺(tái)接受用戶(hù)交互,而任務(wù)A則在后臺(tái)等待被恢復(fù)。

【注意:】后臺(tái)中可以同時(shí)擁有多個(gè)任務(wù),但是如果用戶(hù)同時(shí)運(yùn)行了很多后臺(tái)任務(wù),系統(tǒng)為了回收內(nèi)存可能銷(xiāo)毀一些后臺(tái)的Activity,從而導(dǎo)致Activity的狀態(tài)丟失。

? ? ? ? 因?yàn)榛赝硕褩V械腁ctivity不曾被重新排列,因此如果允許用戶(hù)從多個(gè)Activity中啟動(dòng)一個(gè)特殊的Activity,那么就會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例,并且在堆棧的頂部彈出(而不是把之前的Activity實(shí)例帶到堆棧的頂端)。這樣在你的應(yīng)用程序中一個(gè)Activity就可能被實(shí)例化多次(甚至來(lái)自不同任務(wù))。

(三)、Activity和Task的默認(rèn)行為的總結(jié):

1、當(dāng)Activity A啟動(dòng)Activity B時(shí),ActivityA被終止,但是系統(tǒng)保留了它的狀態(tài)(如滾動(dòng)條的位置和錄入表單的文本)。如果用戶(hù)在Activity B中按回退按鈕,Activity A會(huì)使用被保存的狀態(tài)來(lái)進(jìn)行恢復(fù)。

2、當(dāng)用戶(hù)通過(guò)按主頁(yè)(Home)按鈕離開(kāi)一個(gè)任務(wù)時(shí),當(dāng)前的Activity會(huì)被終止,并且被放入后臺(tái)。系統(tǒng)會(huì)保留任務(wù)中每個(gè)Activity的狀態(tài)。如果用戶(hù)隨后通過(guò)選擇啟動(dòng)圖標(biāo)來(lái)恢復(fù)這個(gè)任務(wù),那么任務(wù)會(huì)來(lái)到前臺(tái),并且恢復(fù)了堆棧頂部的Activity。

3、如果用戶(hù)按下回退按鈕,當(dāng)前的Activity會(huì)從堆棧中被彈出并且被銷(xiāo)毀。堆棧中的前一個(gè)Activity會(huì)被恢復(fù)。Activity被銷(xiāo)毀時(shí),系統(tǒng)不會(huì)保留Activity的狀態(tài)。

4、Activity能夠被實(shí)例化多次,甚至來(lái)自其他任務(wù)。


五、Activity啟動(dòng)模式:

????????在Android中每個(gè)界面都是一個(gè)Activity,切換界面操作其實(shí)是多個(gè)不同Activity之間的實(shí)例化操作。在Android中Activity的啟動(dòng)模式?jīng)Q定了Activity的啟動(dòng)運(yùn)行方式。Android總Activity的啟動(dòng)模式分為四種:

(一)、Activity啟動(dòng)模式設(shè)置:


(二)、Activity的四種啟動(dòng)模式:

? ? 1.?standard(備注:standard是系統(tǒng)默認(rèn)的啟動(dòng)模式。)

? ? ? ? 標(biāo)準(zhǔn)啟動(dòng)模式,每次激活A(yù)ctivity時(shí)都會(huì)創(chuàng)建Activity,并放入任務(wù)棧中。每個(gè)窗體的getTaskId()保持不變,但是this.hashCode()發(fā)生改變。

? ? 2.?singleTop

? ? ? ? 如果在任務(wù)的棧頂正好存在該Activity的實(shí)例, 就重用該實(shí)例,而不會(huì)創(chuàng)建新的Activity對(duì)象,不過(guò)它會(huì)調(diào)用onNewIntent()方法。如果棧頂部不存在就會(huì)創(chuàng)建新的實(shí)例并放入棧頂(即使棧中已經(jīng)存在該Activity實(shí)例,只要不在棧頂,都會(huì)創(chuàng)建實(shí)例)。會(huì)回調(diào)onNewIntent()方法。

? ? 3.?singleTask

? ? ? ? 如果在棧中已經(jīng)有該Activity的實(shí)例,就重用該實(shí)例(會(huì)調(diào)用實(shí)例的onNewIntent())。重用時(shí),會(huì)讓該實(shí)例回到棧頂,因此在它上面的實(shí)例將會(huì)被移除棧。如果棧中不存在該實(shí)例,將會(huì)創(chuàng)建新的實(shí)例放入棧中。

????????和singleTop在名字上即可看出區(qū)別,即singleTop每次只檢測(cè)當(dāng)前棧頂?shù)腁ctivity是否是我們需要請(qǐng)求創(chuàng)建的,而singleTask則會(huì)檢測(cè)棧中全部的Activity對(duì)象,從上向下,如果檢測(cè)到是我們所請(qǐng)求的則會(huì)消滅此Activity對(duì)象上面的對(duì)象,直接把檢測(cè)到的我們需要的Activity置為棧頂。

? ? 4.?singleInstance

? ? ? ? 與singleTask模式的區(qū)別是存放singleInstance模式窗口對(duì)象的回退棧不能有其他任何窗口對(duì)象。因此如果該窗口不存在,則要新建任務(wù)來(lái)存放該singleInstance模式窗口。也就是說(shuō)getTaskId()會(huì)發(fā)現(xiàn)任務(wù)id發(fā)生了變化。

????????此啟動(dòng)模式和我們使用的瀏覽器工作原理類(lèi)似,在多個(gè)程序中訪問(wèn)瀏覽器時(shí),如果當(dāng)前瀏覽器沒(méi)有打開(kāi),則打開(kāi)瀏覽器,否則會(huì)在當(dāng)前打開(kāi)的瀏覽器中訪問(wèn)。此模式會(huì)節(jié)省大量的系統(tǒng)資源,因?yàn)樗鼙WC要請(qǐng)求的Activity對(duì)象在當(dāng)前的棧中只存在一個(gè)。

總之,在開(kāi)發(fā)Android項(xiàng)目時(shí),巧妙設(shè)置Activity的啟動(dòng)模式會(huì)節(jié)省系統(tǒng)開(kāi)銷(xiāo)和提高程序運(yùn)行效率。

【備注:】

android:screenOrientation="portrait"

android:configChanges="keyboardHidden|orientation|screenSize"

1、不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次,切豎屏?xí)r會(huì)執(zhí)行兩次

2、設(shè)置Activity的android:configChanges="orientation"時(shí),切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫、豎屏?xí)r只會(huì)執(zhí)行一次

3、設(shè)置Activity的android:configChanges="keyboardHidden"時(shí),切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫、豎屏?xí)r只會(huì)執(zhí)行一次

4、設(shè)置Activity的android:configChanges="orientation|screenSize|keyboardHidden"時(shí),切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,169評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,722評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,465評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,823評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,000評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,513評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,722評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,125評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,430評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,237評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,482評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容