Android启动Activity的两种方式与四种启动模式
1、在一個(gè)Activity中調(diào)用startActivity()方法
2、在一個(gè)Activity中調(diào)用startActivityRequest()方法。
重寫onActivityResult方法,用來接收B回傳的數(shù)據(jù)。在B中回傳數(shù)據(jù)時(shí)采用setResult方法,并且之后要調(diào)用finish方法。
第一種方法簡(jiǎn)單直接。但是如果A調(diào)用B,并傳遞數(shù)據(jù),同時(shí)B對(duì)數(shù)據(jù)處理后又返回給A,A再將數(shù)據(jù)顯示出來。碰到這種情況,用第一種方法需要在A的onCreate()里面判斷是第一次生成的界面,還是由B打開的A。這樣比較麻煩,用第二種方法就簡(jiǎn)單了,在A的onCreate()只用寫一次生成的界面的內(nèi)容。在A的onActivityResult方法里放B處理完數(shù)據(jù)后的內(nèi)容就可以了。
下面是第二中方法的具體講解:
MainActivity 中部分代碼 Intent intent = new Intent(MainActivity.this, ActivityA.class); startActivity(intent);Intent intent = new Intent(MainActivity.this, ActivityB.class); startActivityForResult(intent, RequestCodeB);
Intent intent = new Intent(MainActivity.this, ActivityC.class); startActivityForResult(intent, RequestCodeC); /******************************************************************************** * Activity回調(diào) *******************************************************************************/ public static final int RequestCodeA = 10001; public static final int RequestCodeB = 10002; public static final int RequestCodeC = 10003; protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RequestCodeA && resultCode == RESULT_OK) { Log.d("MainActivity", "onActivityResultA"); } else if (requestCode == RequestCodeB && resultCode == RESULT_OK) { Log.d("MainActivity", "onActivityResultB"); } else if (requestCode == RequestCodeC && resultCode == RESULT_OK) { String string=data.getStringExtra("data"); Log.d("MainActivity", "onActivityResultC:"+string); } }; public class ActivityA extends Activity { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { finish(); } return false; } } public class ActivityB extends Activity { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { setResult(Activity.RESULT_OK); finish(); } return false; } } public class ActivityC extends Activity { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { Intent data = new Intent(); data.putExtra("data", "ActivityC"); setResult(Activity.RESULT_OK,data); finish(); } return false; } }
?
***************************************************************************************
Activity啟動(dòng)方式有四種,分別是:
standard
singleTop
singleTask
singleInstance
可以根據(jù)實(shí)際的需求為Activity設(shè)置對(duì)應(yīng)的啟動(dòng)模式,從而可以避免創(chuàng)建大量重復(fù)的Activity等問題。
設(shè)置Activity的啟動(dòng)模式,只需要在AndroidManifest.xml里對(duì)應(yīng)的<activity>標(biāo)簽設(shè)置android:launchMode屬性,例如:
下面是這四種模式的作用:
standard
默認(rèn)模式,可以不用寫配置。在這個(gè)模式下,都會(huì)默認(rèn)創(chuàng)建一個(gè)新的實(shí)例。因此,在這種模式下,可以有多個(gè)相同的實(shí)例,也允許多個(gè)相同Activity疊加。
例如:
若我有一個(gè)Activity名為A1, 上面有一個(gè)按鈕可跳轉(zhuǎn)到A1。那么如果我點(diǎn)擊按鈕,便會(huì)新啟一個(gè)Activity A1疊在剛才的A1之上,再點(diǎn)擊,又會(huì)再新啟一個(gè)在它之上……
點(diǎn)back鍵會(huì)依照棧順序依次退出。
singleTop
可以有多個(gè)實(shí)例,但是不允許多個(gè)相同Activity疊加。即,如果Activity在棧頂?shù)臅r(shí)候,啟動(dòng)相同的Activity,不會(huì)創(chuàng)建新的實(shí)例,而會(huì)調(diào)用其onNewIntent方法。
例如:
若我有兩個(gè)Activity名為B1,B2,兩個(gè)Activity內(nèi)容功能完全相同,都有兩個(gè)按鈕可以跳到B1或者B2,唯一不同的是B1為standard,B2為singleTop。
若我意圖打開的順序?yàn)锽1->B2->B2,則實(shí)際打開的順序?yàn)锽1->B2(后一次意圖打開B2,實(shí)際只調(diào)用了前一個(gè)的onNewIntent方法)
若我意圖打開的順序?yàn)锽1->B2->B1->B2,則實(shí)際打開的順序與意圖的一致,為B1->B2->B1->B2。
singleTask
只有一個(gè)實(shí)例。在同一個(gè)應(yīng)用程序中啟動(dòng)他的時(shí)候,若Activity不存在,則會(huì)在當(dāng)前task創(chuàng)建一個(gè)新的實(shí)例,若存在,則會(huì)把task中在其之上的其它Activity destory掉并調(diào)用它的onNewIntent方法。
如果是在別的應(yīng)用程序中啟動(dòng)它,則會(huì)新建一個(gè)task,并在該task中啟動(dòng)這個(gè)Activity,singleTask允許別的Activity與其在一個(gè)task中共存,也就是說,如果我在這個(gè)singleTask的實(shí)例中再打開新的Activity,這個(gè)新的Activity還是會(huì)在singleTask的實(shí)例的task中。
例如:
若我的應(yīng)用程序中有三個(gè)Activity,C1,C2,C3,三個(gè)Activity可互相啟動(dòng),其中C2為singleTask模式,那么,無論我在這個(gè)程序中如何點(diǎn)擊啟動(dòng),如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多個(gè)實(shí)例,但是C2只會(huì)存在一個(gè),并且這三個(gè)Activity都在同一個(gè)task里面。
但是C1->C2->C3->C2->C3->C1-C2,這樣的操作過程實(shí)際應(yīng)該是如下這樣的,因?yàn)閟ingleTask會(huì)把task中在其之上的其它Activity destory掉。
操作:C1->C2 ? ? ? ? ?C1->C2->C3? ? ? ? ??C1->C2->C3->C2 ? ? ? ? ? ?C1->C2->C3->C2->C3->C1 ? ? ? ? ? ??C1->C2->C3->C2->C3->C1-C2
實(shí)際:C1->C2 ? ? ? ? ?C1->C2->C3 ? ? ? ? ?C1->C2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?C1->C2->C3->C1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? C1->C2
若是別的應(yīng)用程序打開C2,則會(huì)新啟一個(gè)task。
如別的應(yīng)用Other中有一個(gè)activity,taskId為200,從它打開C2,則C2的taskIdI不會(huì)為200,例如C2的taskId為201,那么再從C2打開C1、C3,則C2、C3的taskId仍為201。
注意:如果此時(shí)你點(diǎn)擊home,然后再打開Other,發(fā)現(xiàn)這時(shí)顯示的肯定會(huì)是Other應(yīng)用中的內(nèi)容,而不會(huì)是我們應(yīng)用中的C1 C2 C3中的其中一個(gè)。
singleInstance
只有一個(gè)實(shí)例,并且這個(gè)實(shí)例獨(dú)立運(yùn)行在一個(gè)task中,這個(gè)task只有這個(gè)實(shí)例,不允許有別的Activity存在。
例如:
程序有三個(gè)ActivityD1,D2,D3,三個(gè)Activity可互相啟動(dòng),其中D2為singleInstance模式。那么程序從D1開始運(yùn)行,假設(shè)D1的taskId為200,那么從D1啟動(dòng)D2時(shí),D2會(huì)新啟動(dòng)一個(gè)task,即D2與D1不在一個(gè)task中運(yùn)行。假設(shè)D2的taskId為201,再從D2啟動(dòng)D3時(shí),D3的taskId為200,也就是說它被壓到了D1啟動(dòng)的任務(wù)棧中。
若是在別的應(yīng)用程序打開D2,假設(shè)Other的taskId為200,打開D2,D2會(huì)新建一個(gè)task運(yùn)行,假設(shè)它的taskId為201,那么如果這時(shí)再從D2啟動(dòng)D1或者D3,則又會(huì)再創(chuàng)建一個(gè)task,因此,若操作步驟為other->D2->D1,這過程就涉及到了3個(gè)task了。
在IntentActivity中重寫下列方法:onCreate onStart onRestart? onResume? onPause onStop onDestroy? onNewIntent
1、其他應(yīng)用發(fā)Intent,執(zhí)行下列方法:
onCreate
onStart
onResume
發(fā)Intent的方法:
Uri uri = Uri.parse("philn://blog.163.com"); Intent it = new Intent(Intent.ACTION_VIEW, uri); startActivity(it);2、接收Intent聲明:
<activity android:name=".IntentActivity" android:launchMode="singleTask"android:label="@string/testname"><intent-filter><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="philn"/></intent-filter> </activity>3、如果IntentActivity處于任務(wù)棧的頂端,也就是說之前打開過的Activity,現(xiàn)在處于onPause、onStop狀態(tài)的話,其他應(yīng)用再發(fā)送Intent的話,執(zhí)行順序?yàn)?#xff1a;
onNewIntent,onRestart,onStart,onResume。
在Android應(yīng)用程序開發(fā)的時(shí)候,從一個(gè)Activity啟動(dòng)另一個(gè)Activity并傳遞一些數(shù)據(jù)到新的Activity上非常簡(jiǎn)單,但是當(dāng)您需要讓后臺(tái)運(yùn)行的Activity回到前臺(tái)并傳遞一些數(shù)據(jù)可能就會(huì)存在一點(diǎn)點(diǎn)小問題。
首先,在默認(rèn)情況下,當(dāng)您通過Intent啟到一個(gè)Activity的時(shí)候,就算已經(jīng)存在一個(gè)相同的正在運(yùn)行的Activity,系統(tǒng)都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例并顯示出來。為了不讓Activity實(shí)例化多次,我們需要通過在AndroidManifest.xml配置activity的加載方式(launchMode)以實(shí)現(xiàn)單任務(wù)模式,如下所示:
<activity?android:label="@string/app_name"?android:launchmode="singleTask"android:name="Activity1"></activity>launchMode為singleTask的時(shí)候,通過Intent啟到一個(gè)Activity,如果系統(tǒng)已經(jīng)存在一個(gè)實(shí)例,系統(tǒng)就會(huì)將請(qǐng)求發(fā)送到這個(gè)實(shí)例上,但這個(gè)時(shí)候,系統(tǒng)就不會(huì)再調(diào)用通常情況下我們處理請(qǐng)求數(shù)據(jù)的onCreate方法,而是調(diào)用onNewIntent方法,如下所示:
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);setIntent(intent);//must store the new intent unless getIntent() will return the old oneprocessExtraData(); }不要忘記,系統(tǒng)可能會(huì)隨時(shí)殺掉后臺(tái)運(yùn)行的?Activity?,如果這一切發(fā)生,那么系統(tǒng)就會(huì)調(diào)用?onCreate?方法,而不調(diào)用?onNewIntent?方法,一個(gè)好的解決方法就是在?onCreate?和?onNewIntent?方法中調(diào)用同一個(gè)處理數(shù)據(jù)的方法,如下所示:
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.main); processExtraData(); } protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent);processExtraData() } private void processExtraData(){ Intent intent = getIntent(); //use the data received here }二、onNewIntent()的setIntent()和getIntent()
@Override protected void onNewIntent(Intent intent) {super.onNewIntent(intent); // setIntent(intent); int data = getIntent().getIntExtra("HAHA", 0);// int data = intent.getIntExtra("HAHA", 0); }如果沒有調(diào)用setIntent(intent),則getIntent()獲取的數(shù)據(jù)將不是你所期望的。但是使用intent.getInXxx,貌似可以獲得正確的結(jié)果。
注意這句話:
Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.
所以最好是調(diào)用setIntent(intent),這樣在使用getIntent()的時(shí)候就不會(huì)有問題了。
?
轉(zhuǎn)載于:https://www.cnblogs.com/chenxibobo/p/6136626.html
總結(jié)
以上是生活随笔為你收集整理的Android启动Activity的两种方式与四种启动模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Linux下使用iconv转换字符串编
- 下一篇: (王道408考研操作系统)第二章进程管理