標籤:android activity載入方式 activity載入方式 activity與task android task
Activity四種載入模式 我們知道在配置Activity的時候可以指定android:lauchMode屬性,該屬性用於配置該Activity的載入模式,概述行支援以下四種:
1.standard: 標準模式,這是預設的載入模式.
2.singleTop: Task頂單例模式. 3.singleTask: Task內單例模式.
4.singleInstance: 全域單例模式.
那麼Activity為什麼需要制定載入模式呢?
由於在Android上啟動一個應用後,系統會自動的建立一個屬於該應用的Task,也可以理解為Activity棧,先建立的Activity在棧底,後建立的在棧頂部,而Android並沒有為我們提供操作Task的相關API,我們無法直接去操作這個Task,只能通過控制Activity的載入模式來控制Activity與Task之間的載入關係了.
1.standard模式
以這種模式啟動的Activity會建立一個新的Activity執行個體,並加入到已存在的Task棧中,這種模式不會啟動新的.
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); this.setContentView(ll); TextView tv = new TextView(this); tv.setText("Activity為: " + this.toString() + "\n" + ", Task ID 為:" + this.getTaskId()); Button button = new Button(this); button.setText("啟動Activity"); ll.addView(tv); ll.addView(button); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MainActivity.class); startActivity(intent); } } ); }}
由於Activity預設的載入模式就是這種,所以不用再AndroidManifest.xml檔案中去定義.每次點擊按鈕之後,都會產生一個新的Activity並加入到棧中,在產生多個之後,不停地按back鍵,可以看到棧中的Activity一個一個的顯示出來.仔細觀察每個Activity的HashCode值會有不同,但TaskId都是相同的,說明不會建立新的Task.
2.singleTop模式
這種模式建立的Activity也是和standard一樣直接放棧頂,不同之處在於,singleTop模式在啟動Activity之前會檢測當前棧頂Activity是否和當前需要啟動的Activity是同一類,如果是同一類,系統將直接複用已經擁有的Activity,不是同一類則會和standard模式一樣建立一個Activity放到棧頂.
代碼和上面的一模一樣,需要在AndroidManifest.xml中加入 android:launchMode="singleTop"
不管怎麼點擊按鈕,,,,都不會有反應的.
3.singleTask模式
singleTask模式在載入Activity的時候,只允許同一個Task中存在該Activity的一個執行個體.建立的時候分三種情況考慮:
1.如果Task中不存在該Activity的執行個體,則建立一個加入其中
2.如果Task中存在並且正好位於棧頂,則與singleTop模式操作方法相同,沒有反應.
3.如果存在Task中,並且不在棧頂,則先將Task中位於該Activity之上的Activity全部彈出,使其置於棧頂.
注意在AndroidManifest.xml檔案中做出相應的更改.
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); this.setContentView(ll); TextView tv = new TextView(this); tv.setText("Activity為: " + this.toString() + "\n" + ", Task ID 為:" + this.getTaskId()); Button button = new Button(this); button.setText("啟動Activity"); ll.addView(tv); ll.addView(button); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } } ); }}public class SecondActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); this.setContentView(ll); TextView tv = new TextView(this); tv.setText("Activity為: " + this.toString() + "\n" + ", Task ID 為:" + this.getTaskId()); Button button = new Button(this); button.setText("啟動Activity"); ll.addView(tv); ll.addView(button); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity.this,MainActivity.class); startActivity(intent); } } ); }}
點擊第一個activity中的按鈕後,會啟動第二個activity,在第二個activity中點擊按鈕,會將第二個activity中彈出,顯示出第一個activity.在第一個activity中按下back按鍵,會直接退出程式,這就說明第二個activity消失了.如果是在第二個activity中按下back鍵,則會回退到第一個activity中去.
4.singleInstance模式
這個載入模式會和前面幾個有較大的區別,系統保證無論從哪個Task中啟動目標activity,智慧建立一個目標activity執行個體,並會使用一個全新的Task棧來存放該執行個體.在建立的時候分如下的兩種情況:
1.目標Activity沒有執行個體存在於Task中,則建立目標Activity執行個體後,存放在一個單獨的Task中. 2.存在執行個體於Task中,不管是哪個Task(不管是後面建立的Task還是主程式在最初建立的Task),系統都會將那個Task轉入前台,使其顯示出來.
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); this.setContentView(ll); TextView tv = new TextView(this); tv.setText("Activity為: " + this.toString() + "\n" + ", Task ID 為:" + this.getTaskId()); Button button = new Button(this); button.setText("啟動Activity"); ll.addView(tv); ll.addView(button); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } } ); }}public class SecondActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); this.setContentView(ll); TextView tv = new TextView(this); tv.setText("Activity為: " + this.toString() + "\n" + ", Task ID 為:" + this.getTaskId()); Button button = new Button(this); button.setText("啟動Activity"); ll.addView(tv); ll.addView(button); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction("org.crazyit.intent.action.CRAZYIT_ACTION"); startActivity(intent); } } ); }} <activity android:name="com.example.dada.testapplication.SecondActivity" android:launchMode="singleInstance" android:exported="true" android:label="@string/title_activity_second" > <intent-filter> <action android:name="org.crazyit.intent.action.CRAZYIT_ACTION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
可以看到在啟動了第二個Activity之後,其Task ID變化了,而在第二個Activity正在顯示的時候,點擊按鈕沒什麼反應.回退到第一個activity再建立第二個Acitivity,Task的ID又出現了不同的數值.
熟悉了上面的四種載入模式之後,我們就能很方便的管理Activity和Task之間的關係了~~~
Android中Activity四種載入模式