Android組件之Activity

Activity總結

 

序言:Activity作爲Android四大組件之一,其重要性不言而喻。


本文目錄結構:

1.        Acticity是什麼

2.        Activity的創建

3.        Activity的生命週期

4.        Activity的啓動方式

5.        Activity 之間通信

6.        Activity 的 IntentFilter

7.        Activity的launchMode

 

一、Acticity是什麼

Activity是這樣一個程序組件,它爲用戶提供一個用於任務交互的畫面。例如,撥打電話,拍照,發郵件。或者查看地圖。每一個activity都被分配一個窗口。在這個窗口裏,你可以繪製用戶交互的內容。這個窗口通常佔滿屏幕,但也有可能比屏幕小,並且浮在其它窗口的上面。


二、Activity的創建

創建一個activity,你必須繼承Activity類或者Activity的子類。在你的創建的Activity中,你需要實現系統回調的回調方法,以便當activity被創建、停止、恢復或摧毀時調用。兩個最重要的回調方法是:

       1onCreate()

你必須實現這個方法。系統調用它當創建你的activity的時候。在你的實現中,你應該初始化你的activity的基本的組件。更重要的是,這裏就是你必須調用setContentView()來定義activity用戶接口而已的地方。

       2onPause()

       系統調用這個方法當用戶離開你的activity(雖然不總是意味着activity被摧毀)。這通常是你應該提交任何變    化,那此將會超越user session而存在的(因爲用戶可能不再回來)。

 


android 中創建一個 Activity 是很簡單的事情,編寫一個繼承自 android.app.Activity Java類並在 AndroidManifest.xml聲明即可。

Activity 文件:

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //使用setContentView用來顯示某個視圖
        setContentView(R.layout.main);
    }
}


AndroidManifest.xml:

<activity
         android:name=". MainActivity "
         android:label="@string/app_name">
      <intent-filter>
          <actionandroid:name="android.intent.action.MAIN" />
          <categoryandroid:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>  


<action> 元素指定程序的入口。 <category> 指出該activity應該被列如系統的啓動器(launcher)(允許用戶啓動它)

<!--
1
、一個應用程序可以有多個Activity,每個Activity是同級別的,那麼在啓動程序時,最先啓動哪個Activity呢?
有些程序可能需要顯示在程序列表裏,有些不需要。怎麼定義呢?
android.intent.action.MAIN
決定應用程序最先啓動的Activity
android.intent.category.LAUNCHER
決定應用程序是否顯示在程序列表裏
2
、因爲你的程序可能有很多個activity只要xml配置文件中有這麼一個intent-filter,而且裏面有這個launcher,那麼這個activity就是點擊程序時最先運行的那個activity
3
、現在只有一個activity,那麼加不加就沒有關係了。用於模擬器啓動時設置爲默認打開爲的activity
-->

 

三、Activity的生命週期 


public classActivity extends ApplicationContext {

        protected void onCreate(Bundle savedInstanceState);

        protected void onStart();

        protected void onRestart();

        protected void onResume();

        protected void onPause();

        protected void onStop();

        protected void onDestroy();
        
}<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);"> </span>

由圖可知:

   在一個Activity正常啓動過程中,這些方法調用的順序是onCreate -> onStart -> onResume;

     在Activity被kill掉的時候方法順序是onPause -> onStop -> onDestroy,此爲一個完整的Lifecycle。

     那麼對於中斷處理(比如電話來了),則是onPause -> onStop,恢復時onStart -> onResume;

     如果當前應用程序的是一個Theme爲Translucent(半透明) 或者Dialog 的Activity那麼中斷就是onPause ,恢復的時候onResume。

     假設在當前的ActivityA中啓動ActivityB,調用順序爲onPause(A)-> onCreate(B)-> onStart(B) -> onResume(B)-> onStop(A).


各種方法在系統中的作用及我們應該做什麼:

  onCreate:在這裏創建界面,做一些數據的初始化工作;

  onStart: 到這一步變成“用戶可見不可交互”的狀態;

  onResume:變成和用戶可交互的,(在Activity棧系統通過棧的方式管理這些Activity,即當前Activity在棧的最上端,運行完彈出棧,則回到上一個Activity);

  onPause:到這一步是可見但不可交互的,系統會停止動畫等消耗CPU的事情。從上文的描述已經知道,應該在這裏保存你的一些數據,因爲這個時候你的程序的優先級降低,有可能被系統收回。在這裏保存的數據,應該在onResume裏讀出來。

  onStop:變得不可見 ,被下一個activity覆蓋了

  onDestroy:這是Activity被kill前最後一個被調用方法了,可能是其他類調用finish方法或者是系統爲了節省空間將它暫時性的幹掉,可以用isFinishing()來判斷它,如果你有一個Progress Dialog在線程中運行,請在onDestroy裏把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會拋異常。

onPause,onstop, onDestroy,三種狀態下 activity都有可能被系統kill 掉。

 

四、Activity的啓動方式

啓動一個Activity


你可以通過調用startActivity()啓動一個其他的activity, 並傳遞一個 Intent , 它用於描述activity。 intent指定了你想要啓動的activity,或者指定了你想展現的動作(系統幫你選擇合適的activity,它可能來自於其他的程序)。 intent也可以攜帶比較小量的數據,用於啓動acitivity。

在你自己的應用中,你經常會簡單地啓動一個已知的activity,通過創建一個明確的intent。這個intent指定了activity的類名。 例如下面演示瞭如何啓動一個叫SignInActivity的activity:

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

然而,你的程序可能想要展示某些動作,例如發郵件,短信,微博,或者使用你activity中的數據。這時候,你就不應該使用自己的activity來做這些工作。你應該調用系統中其他程序提供的響應功能。這是intent真正體現其價值的地方。你可以創建一個描述了響應動作的intent,然後系統來爲你挑選完成任務的程序。如果有多個選擇,系統會提示用戶進行選擇。例如你想讓用戶發郵件,你可以創建下面的intent:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

      EXTRA_EMAIL 是一個郵件intent中添加的額外字符串數組,它指定了郵件該發給哪些郵件地址。當一個郵件程序響應了這個intent,它將讀取這些地址,並把他們放置到郵件表單的被髮送人欄。這時,郵件程序被啓動。當用戶完成了發送操作,你的activity會被恢復。


啓動一個帶返回結果的activity

有時候,你想要啓動一個activity,並從這個activty獲得一個結果。這時,要通過 startActivityForResult()(取代startActivity())來啓動activity。然後通過實現onActivityResult()回調方法來獲得返回後的結果。當這個後續的activity被關閉,它將發送一個 Intent 給 onActivityResult() 方法。


例如,你可能想要取一個聯繫人的信息。下面介紹怎麼創建intent並處理結果:

private void pickContact() {
    // Create an intent to "pick" a contact, as defined by the content provider URI
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
}

這個例子展示了使用onActivityResult() 來獲取結果的基本方法。第一步要判斷請求是否被成功響應,通過判斷resultCode 是不是RESULT_OK,然後判斷這個響應是不是針對相應的請求,此時只要判斷requestCode 和發送時提供的第二個參數 startActivityForResult() 是否相匹配。最後,查詢 Intent中的data信息。 (data 參數)。


這個過程中,ContentResolver 開啓了一個查詢而不是content provider, 它返回一個 Cursor ,這將允許數據被讀取。更多content provider相關信息,請查閱ContentProviders 文檔。


關於intent的更多信息,查看 Intentsand Intent Filters 文檔。


關閉Activity


你可以通過調用finish() 來終止activity。你也可以調用finishActivity() 來終止你之前啓動了的一個獨立activity。

注意: 多數情況下,你不應該明確地通過這些方式來關閉acitivity。就像下面要討論的activity的生命週期。系統會爲你管理。所以你不必關閉他們。調用這些方法將有悖於用戶體驗。它們僅用於你絕對不想讓用戶再返回這個activity的實例。

 

五、Activity之間的通信

使用 Intent通信

在 Android 中,不同的 Activity 實例可能運行在一個進程中,也可能運行在不同的進程中。因此我們需要一種特別的機制幫助我們在 Activity 之間傳遞消息。Android 中通過 Intent 對象來表示一條消息,一個 Intent 對象不僅包含有這個消息的目的地,還可以包含消息的內容,這好比一封 Email,其中不僅應該包含收件地址,還可以包含具體的內容。對於一個 Intent 對象,消息“目的地”是必須的,而內容則是可選項。


這裏拿發送,接受郵件做例子:

如果我們想要給“收件人”Activity 說點什麼的話,那麼可以通過下面這封“e-mail”來將我們消息傳遞出去:

Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
  // 創建一個帶“收件人地址”的 email 
 Bundle bundle =new Bundle();// 創建 email 內容
 bundle.putBoolean("boolean_key", true);// 編寫內容
 bundle.putString("string_key", "string_value"); 
 intent.putExtra("key", bundle);// 封裝 email 
 startActivity(intent);// 啓動新的 Activity

那麼收件人該如何收信呢?在 OtherActivity類的 onCreate()或者其它任何地方使用下面的代碼就可以打開這封“e-mail”閱讀其中的信息:

 Intent intent =getIntent();// 收取 email 
 Bundle bundle =intent.getBundleExtra("key");// 打開 email 
 bundle.getBoolean("boolean_key");// 讀取內容
 bundle.getString("string_key");


上面我們通過 bundle對象來傳遞信息,bundle維護了一個 HashMap<String,Object>對象,將我們的數據存貯在這個HashMap中來進行傳遞。但是像上面這樣的代碼稍顯複雜,因爲Intent內部爲我們準備好了一個 bundle,所以我們也可以使用這種更爲簡便的方法:

Intent intent =new Intent(EX06.this,OtherActivity.class); 
 intent.putExtra("boolean_key", true); 
 intent.putExtra("string_key", "string_value"); 
 startActivity(intent);

接收: 

Intent intent=getIntent(); 
 intent.getBooleanExtra("boolean_key",false); 
 intent.getStringExtra("string_key");

使用 SharedPreferences

SharedPreferences使用 xml格式爲 Android應用提供一種永久的數據存貯方式。對於一個Android應用,它存貯在文件系統 /data/data/your_app_package_name/shared_prefs/目錄下,可以被處在同一個應用中的所有

Activity 訪問。Android提供了相關的 API來處理這些數據而不需要程序員直接操作這些文件或者考慮數據同步問題

// 寫入 SharedPreferences 
 SharedPreferences preferences = g
 etSharedPreferences("name", MODE_PRIVATE); 
 Editor editor = preferences.edit(); 
 editor.putBoolean("boolean_key", true); 
 editor.putString("string_key", "string_value"); 
 editor.commit(); 
        
 // 讀取 SharedPreferences 
 SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE); 
 preferences.getBoolean("boolean_key", false); 
 preferences.getString("string_key", "default_value");

其它方式

Android 提供了包括SharedPreferences在內的很多種數據存貯方式,比如SQLite,文件等,程序員可以通過這些API實現Activity之間的數據交換。如果必要,我們還可以使用IPC方式。

 

六、Activity Intent Filter

IntentFilter描述了一個組件願意接收什麼樣的Intent對象,Android將其抽象爲android.content.IntentFilter類。在AndroidAndroidManifest.xml配置文件中可以通過<intent-filter >節點爲一個Activity指定其Intent Filter,以便告訴系統該Activity可以響應什麼類型的Intent
當程序員使用startActivity(intent)來啓動另外一個Activity時,如果直接指定intent了對象的Component屬性,那麼Activity Manager將試圖啓動其Component屬性指定的Activity。否則Android將通過Intent的其它屬性從安裝在系統中的所有Activity中查找與之最匹配的一個啓動,如果沒有找到合適的Activity,應用程序會得到一個系統拋出的異常。這個匹配的過程如下:
 Activity 中 Intent Filter 的匹配過程

Action 匹配

Action 是一個用戶定義的字符串,用於描述一個 Android應用程序組件,一個 Intent Filter可以包含多個 Action。在 AndroidManifest.xml Activity定義時可以在其 <intent-filter >節點指定一個 Action列表用於標示 Activity所能接受的動作,例如:

<intent-filter > 
 <action android:name="android.intent.action.MAIN" /> 
 <action android:name="com.zy.myaction" /> 
 </intent-filter>

如果我們在啓動一個 Activity時使用這樣的 Intent對象:

Intent intent =new Intent(); 
intent.setAction("com.zy.myaction");

那麼所有的 Action列表中包含了com.zy.myaction Activity都將會匹配成功。

Android 預定義了一系列的 Action分別表示特定的系統動作。這些 Action通過常量的方式定義在 android.content. Intent中,以ACTION_開頭。我們可以在 Android提供的文檔中找到它們的詳細說明。

 

URI 數據匹配

一個 Intent可以通過 URI攜帶外部數據給目標組件。在 <intent-filter >節點中,通過 <data/>節點匹配外部數據。

mimeType 屬性指定攜帶外部數據的數據類型,scheme指定協議,hostportpath指定數據的位置、端口、和路徑。如下:

<data android:mimeType="mimeType" android:scheme="scheme" 
 android:host="host" android:port="port" android:path="path"/>

如果在 Intent Filter中指定了這些屬性,那麼只有所有的屬性都匹配成功時 URI數據匹配纔會成功。

Category 類別匹配

<intent-filter >節點中可以爲組件定義一個 Category類別列表,當 Intent中包含這個列表的所有項目時 Category類別匹配纔會成功.

 

action、category、data的匹配規則:

a)      action : 能夠過濾匹配到任何一個action 即可

b)      category : 如果有指定category,不管有幾個都要能夠與過濾規則中的任何一個category相同。

c)      data : 與action 相似,能完全匹配到過濾規則中的某一個,注意使用setDataAndType()方法,如果單獨使用setData()或者SetType()會擦除之前設置的data或type.

 

七、Activity的launchMode

使用很簡單,只需要在manifest中對應的Activity元素加入 android:launchMode 屬性即可。如下述代碼

<activity
            android:name=".SingleTaskActivity"
            android:label="singleTask launchMode"
            android:launchMode="singleTask">

接下來就是介紹launchMode的四個值的時刻了。

standard

這是launchMode的默認值,Activity不包含android:launchMode或者顯示設置爲standard的Activity就會使用這種模式。

一旦設置成這個值, 每當有一次Intent請求,就會創建一個新的Activity實例 。舉個例子,如果有10個撰寫郵件的Intent,那麼就會創建10個ComposeMailActivity的實例來處理這些Intent。結果很明顯,這種模式會創建某個Activity的多個實例。

Android 5.0之前的表現

這種Activity新生成的實例會放入發送Intent的Task的棧的頂部。下圖爲啓動同一程序內的Activity。 

standardtopstandard

下面的圖片展示跨程序之間調用,新生成的Activity實例會放入發送IntentTask的棧的頂部,儘管它們屬於不同的程序。 

standardgallery2

但是當我們打開任務管理器,則會有一點奇怪,應該顯示的任務是Gallery,展示的界面卻是另一個程序的Activity(因爲其位於Task的棧頂)。

gallerystandard

這時候如果我們從Gallery應用切換到撥號應用,再返回到Gallery,看到的還是這個非GalleryActivity,如果我們想要對Gallery進行操作,必須按Back鍵返回到Gallery界面纔可以。確實有點不太合理。

Android 5.0及之後表現

對於同一應用內部Activity啓動和5.0之前表現一樣,變化的就是不同應用之間Activity啓動變得合理了。

跨應用之間啓動Activity,會創建一個新的Task,新生成的Activity就會放入剛創建的Task中。如下圖

standardgalleryl

同時任務管理器查看任務也顯得更加合理了。

gallerystandardl1

假設之前存在我們的測試程序,然後從Gallery又分享文件到我們的測試程序,則對應的任務管理器展示效果如下。

gallerystandardl2

使用場景:standard這種啓動模式適合於撰寫郵件Activity或者社交網絡消息發佈Activity。如果你想爲每一個intent創建一個Activity處理,那麼就是用standard這種模式。

singleTop

singleTop其實和standard幾乎一樣,使用singleTopActivity也可以創建很多個實例。唯一不同的就是, 如果調用的目標Activity已經位於調用者的Task的棧頂,則不創建新實例,而是使用當前的這個Activity實例,並調用這個實例的onNewIntent方法  

singletop

 在singleTop這種模式下,我們需要處理應用這個模式的Activity的onCreate()和onNewIntent()兩個方法,確保邏輯正常。

使用場景

關於singleTop一個典型的使用場景就是搜索功能。假設有一個搜索框,每次搜索查詢都會將我們引導至SearchActivity查看結果,爲了更好的交互體驗,我們在結果頁頂部也放置這樣的搜索框。

假設一下,SearchActivity啓動模式爲standard,那麼每一個搜索都會創建一個新的SearchActivity實例,10次查詢就是10個Activity。當我們想要退回到非SearchActivity,我們需要按返回鍵10次,這顯然太不合理了。

但是如果我們使用singleTop的話,如果SearchActivity在棧頂,當有了新的查詢時,不再重新創建SearchAc實例,而是使用當前的SearchActivity來更新結果。當我們需要返回到非SearchActivity只需要按一次返回鍵即可。使用了singleTop顯然比之前要合理。

總結

·        只有在調用者和目標Activity在同一Task中,並且目標Activity位於棧頂,才使用現有目標Activity實例,否則創建新的目標Activity實例。

·        如果是外部程序啓動singleTop的Activity,在Android 5.0之前新創建的Activity會位於調用者的Task中,5.0及以後會放入新的Task中。

singleTask

singleTask這個模式和前面提到的standard和singleTop截然不同。 使用singleTask啓動模式的Activity在系統中只會存在一個實例 。如果這個實例已經存在,intent就會通過onNewIntent()方法傳遞到這個Activity。否則新的Activity實例被創建。

同一程序內

如果系統中不存在singleTaskActivity的實例,那麼就需要創建這個Activity的實例,並且將這個實例放入和調用者相同的Task中並位於棧頂。

singleTask1

如果singleTaskActivity實例已然存在,那麼在Activity回退棧中,所有位於該Activity上面的Activity實例都將被銷燬掉(銷燬過程會調用Activity生命週期回調),這樣使得singleTask Activity實例位於棧頂。與此同時,Intent會通過onNewIntent傳遞到這個SingleTask Activity實例。

singleTaskD

然而在Google關於singleTask 文檔 有這樣一段描述

The system createsa new task and instantiates the activity at the root of the new task.

意思爲 系統會創建一個新的Task,並創建Activity實例放入這個新的Task的底部。

然而實際並非如此,在我的例子中,singleTaskActivity並創建並放入了調用者所在的Task,而不是放入新的Task,使用 adbshell dumpsys activity 便可以進行驗證。

Task id #239
  TaskRecord{428efe30 #239 A=com.thecheesefactory.lab.launchmode U=0 sz=2}
  Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
    Hist #1: ActivityRecord{429a88d0 u0 com.thecheesefactory.lab.launchmode/.SingleTaskActivity t239}
      Intent { cmp=com.thecheesefactory.lab.launchmode/.SingleTaskActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}
    Hist #0: ActivityRecord{425fec98 u0 com.thecheesefactory.lab.launchmode/.StandardActivity t239}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}

然而想要實現文檔的描述也並非不可能,我們需要在設置launchModesingleTask的同時,再加上taskAffinity屬性即可。

<activity
            android:name=".SingleTaskActivity"
            android:label="singleTask launchMode"
            android:launchMode="singleTask"
            android:taskAffinity="">

完成上面的修改,我們看一下效果,Task的變化如下圖。

singleTaskTaskAffinity

同時,系統中的任務管理器效果也會相應變化。

screenshot17

跨應用之間

在跨應用Intent傳遞時,如果系統中不存在singleTask Activity的實例,那麼講創建一個新的Task,然後創建SingleTask Activity的實例,將其放入新的Task中。Task變化如下。

singleTaskAnotherApp1

系統的任務管理器也會如下變化。

singletaskfromapp2

如果singleTaskActivity所在的應用進程存在,但是singleTask Activity實例不存在,那麼從別的應用啓動這個Activity,新的Activity實例會被創建,並放入到所屬進程所在的Task中,並位於棧頂位置。

singleTaskAnotherApp2

更復雜的一種情況,如果singleTaskActivity實例存在,從其他程序被啓動,那麼這個Activity所在的Task會被移到頂部,並且在這個Task中,位於singleTask Activity實例之上的所有Activity將會被正常銷燬掉。如果我們按返回鍵,那麼我們首先會回退到這個Task中的其他Activity,直到當前TaskActivity回退棧爲空時,纔會返回到調用者的Task

singleTaskAnotherApp3

在上圖中,當Task2中的相冊啓動分享調用Task1中的singleTask Activity,而該Activity實例存在,並位於Task1中回退棧中的第三個位置(從上到下順序),那麼位於該Activity上面的兩個Activity實例將會被銷燬掉,使得該Activity實例位於棧頂。此時Task1中的回退棧只剩兩個Activity,如果點擊返回,那麼會退到的不是相冊應用,而是singleTaskActivity棧位置下面的Activity,再次點擊返回方可返回相冊應用。

使用場景

該模式的使用場景多類似於郵件客戶端的收件箱或者社交應用的時間線Activity。上述兩種場景需要對應的Activity只保持一個實例即可,但是也要謹慎使用這種模式,因爲它可以在用戶未感知的情況下銷燬掉其他Activity

singleInstance

這個模式和singleTask差不多,因爲他們在系統中都只有一份實例。唯一不同的就是存放singleInstance Activity實例的Task只能存放一個該模式的Activity實例。如果從singleInstance Activity實例啓動另一個Activity,那麼這個Activity實例會放入其他的Task中。同理,如果singleInstance Activity被別的Activity啓動,它也會放入不同於調用者的Task中。

singleInstance

 雖然是兩個task,但是在系統的任務管理器中,卻始終顯示一個,即位於頂部的Task中。

singleInstances

另外當我們從任務管理器進入這個應用,是無法通過返回鍵會退到Task1的。

好在有辦法解決這個問題,就是之前提到的 taskAffinity="" ,爲launchModesingleInstanceActivity加入這個屬性即可。

<activity
            android:name=".SingleInstanceActivity"
            android:label="singleInstance launchMode"
            android:launchMode="singleInstance"
            android:taskAffinity="">

再次運行修改的代碼,查看任務管理器,這樣的結果就合理了。

screenshot18

使用情況

這種模式的使用情況比較罕見,在Launcher中可能使用。或者你確定你需要使Activity只有一個實例。建議謹慎使用。

IntentFlags

除了在manifest文件中設置launchMode之外,還可以在Intnet中設置flag達到同樣的效果。如下述代碼就可以讓StandardActivitysingleTop模式啓動。

Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
關於Intent Flags這裏暫不做重點介紹,具體可以參考 官方文檔

原文信息

·        UnderstandAndroid Activity’s launchMode: standard,singleTop, singleTask and singleInstance


參考文獻:
http://www.android-doc.com/guide/components/activities.html
http://www.ibm.com/developerworks/cn/opensource/os-cn-android-actvt/
http://blog.csdn.net/qq_25184739/article/details/51347403
http://www.kejik.com/article/21538.html
http://www.cnblogs.com/lyp3314/archive/2011/11/10/2244971.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章