【轉載】做爲Android開發者,你真的熟悉Activity嗎?

學過android的人都知道,activity是最經常使用的四大組件之一,但你真的瞭解透徹activity了嗎?接下來,本人將從activity的正常和異常生命週期、啓動模式、IntentFilter匹配原則、activity的過渡動畫等方面作個總結。javascript

1、 activity的生命週期

正常生命週期

1.正常打開單個Activity,而後退出應用:

這種狀況是最普通的情況,Activity的生命週期會按照上圖從上到下的方式走。即:onCreate –> onStart –> onResume –> 運行–> 按返回鍵結束程序–> onPause–>onStop–>onDestoryphp

2.打開一個Activity A,而後再打開另外一個Activity B

對於A:onCreate –> onStart –> onResume –> A運行 –> A發出打開B的Intent –> onPause–>B可見–>onStop
此時,會打開B,B一樣會經歷一個完整的Activity生命週期。等B結束,A再度可見的時候,A會經歷:onRestart–>onStart–>onResumehtml

注意:B這個Activity是在A的onPause執行後才變成可見狀態的,因此爲了避免影響B的顯示,最好不要在onPause裏執行一些耗時操做,能夠考慮將這些操做放到onStop裏,這時B已經可見了。java

異常狀況生命週期

狀況1.資源相關的系統配置發生改變

資源相關的系統配置發生改變,舉個例子。當前Activity處於豎屏狀態的時候忽然轉成橫屏,系統配置發生了改變,Activity就會銷燬而且重建,其onPause, onStop, onDestory均會被調用。由於實在異常狀況下終止的,因此係統會調用onSaveInstanceState來保存當前Activity狀態。這個方法是在onStop以前,與onPause沒有固定的時序關係。當Activity重建的時候系統會把onSaveInstanceState所保存的Bundle做爲對象傳遞給onRestoreInstanceState和onCreate方法。android

狀況2:資源內存不足致使低優先級Activity被殺死

Activity優先級git

前臺Activity——正在和用戶交互的Activity,優先級最高
可見但非前臺Activity——Activity中彈出的對話框致使Activity可見但沒法交互
後臺Activity——已經被暫停的Activity,優先級最低
系統內存不足是,會按照以上順序殺死Activity,並經過onSaveInstanceState和onRestoreInstanceState這兩個方法來存儲和恢復數據。github

2、activity的啓動模式

四種啓動模式分別是standard(標準模式)、singleTop(棧頂複用模式)、singleTask(棧內複用模式)、singleInstance(單實例模式 – 增強的singleTask模式)web

standard

  • 系統默認啓動模式
  • 不論存在與否,都會從新建立一個新的實例
  • 多實例實現,誰啓動了這個Activity、那麼這個Activity就運行在啓動它那個Activity所在棧

singleTop

  • 判斷須要啓動的Activity是否爲任務棧棧頂 ,若是是,則不會從新建立,若是不是,則會從新建立
  • 不從新建立時候,該Activity的 onNewIntent(Intent intent) 方法會被回調,經過該方法的參數,能夠取出當前請求的信息;
  • 系統可能會殺死該Activity,殺死以後,啓動狀況與第一次啓動相同,因此有必要在onCreate與onNewIntent方法中調用同一個處理數據的方法

    運用場景:常運用於通知欄彈出Notification,點擊Notification跳轉到指定的Activity,設置singleTop模式swift

singleTask

  • 判斷Activity所需任務棧內是否已經存在,若是存在,就把該Activity切換到棧頂(會致使在它之上的都會出棧)
  • 若是所需任務棧都不存在,就會先建立任務棧再建立該Activity
  • 能夠理解爲 頂置Activity+singleTop 的模式

    運用場景:可用來退出整個應用。主界面activity設爲singleTas模式,要退出應用時轉到主activity,從而將主activity之上的activity都清除,而後重寫主activity的onNewIntent()方法,在裏面加上finish(),便可退出全部activity。這種模式還適用於作瀏覽器、微博之類的應用瀏覽器

singleInstance

  • 擁有singleTask的全部特性以外,此模式Activity只能單獨地位於一個新的任務棧中
  • 也就是,Activity啓動以後,就會獨自在一個新的任務棧中,下次確定不會從新建立該Activity,除非被系統殺死

    運用場景:這種模式常運用於須要與程序分離的界面,如在SetupWizard(安裝嚮導)中調用緊急呼叫就是適用這種模式

3、Intent和Intent-filter的匹配規則

一、Intent和Intent Filter的介紹

Intent是抽象的數據結構,包含了一系列描述某個操做的數據,使得程序在運行時能夠在程序中不一樣組件間通訊或啓動不一樣的應用程序。

能夠經過startActivity(Intent)啓動一個Activity,sendBroadcast(Intent))發送廣播發送給感興趣的BroadcastReceiver組件,startService(android.content.Intent))啓動service,bindService()綁定服務。

Intent Filter顧名思義就是Intent的過濾器,組件經過定義Intent Filter能夠決定哪些隱式Intent能夠和該組件進行通信
Intent分爲隱式(implicit)Intent和顯式(explicit)Intent。

顯式Intent一般用於在程序內部組件間通訊,已經明確的定義目標組件的信息,因此不須要系統決策哪一個目標組件處理Intent,以下

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

其中CRListDemo和GoogleMapDemo都是用戶自定義的組件,
隱式Intent不指明目標組件的class,只定義但願的Action及Data等相關信息,由系統決定使用哪一個目標組件。如發送短信

2.Intent和Intent-filter的匹配規則

Android系統經過對Intent和目標組件在AndroidManifest文件中定義的(也能夠在程序中定義Intent Filter)進行匹配決定和哪一個目標組件通信。若是某組件未定義則只能經過顯式的Intent進行通訊。Intent的三個屬性用於對目標組件選取的決策,分別是Action、Data(Uri和Data Type)、Category。匹配規則以下

  • action匹配規則:要求intent中的action 存在 且 必須和過濾規則中的其中一個相同 區分大小寫;
  • category匹配規則:系統會默認加上一個android.intent.category.DEAFAULT,因此intent中能夠不存在category,但若是存在就必須匹配其中一個;
  • data匹配規則:data由兩部分組成,mimeType和URI,要求和action類似。若是沒有指定URI,URI但默認值爲content和file(schema)

3.利用Intent調用其餘常見程序

a. 發送短信

Uri uri = Uri.parse("smsto:15800000000"); Intent i=newIntent(Intent.ACTION_SENDTO, uri); i.putExtra("sms_body", "The SMS text"); startActivity(i);

b. 打電話

Uri dial = Uri.parse("tel:15800000000"); Intent i=newIntent(Intent.ACTION_DIAL, dial); startActivity(i);

c. 發送郵件

Uri email = Uri.parse("mailto:abc@126.com;def@126.com");
Intent i=newIntent(Intent.ACTION_SENDTO, email);
startActivity(i);

d. 拍照

Intent i =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
String folderPath= Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" +File.separator; String filePath= folderPath + System.currentTimeMillis() + ".jpg";newFile(folderPath).mkdirs(); File camerFile=newFile(filePath); i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile)); startActivityForResult(i,1);

e. 瀏覽網頁

Uri web = Uri.parse("http://www.google.com"); Intent i=newIntent(Intent.ACTION_VIEW, web); startActivity(i);

f. 查看聯繫人

Intent i =newIntent();
i.setAction(Intent.ACTION_GET_CONTENT); i.setType("vnd.android.cursor.item/phone"); startActivityForResult(i,1);

4、activity過渡動畫的五種實現

1.使用overridePendingTransition方法實現Activity跳轉動畫

overridePendingTransition方法是Activity中提供的Activity跳轉動畫方法,經過該方法能夠實現Activity跳轉時的動畫效果,簡單例子以下:

Intent intent =newIntent(MainActivity.this, SecondActivity.class); startActivity(intent); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left);

注意:overridePendingTransition在startActivity或者是finish方法馬上執行纔有效

二、使用style的方式定義Activity的切換動畫

(1)定義Application的style

<!-- 系統Application定義 -->
<application Android:allowBackup="true" Android:icon="@mipmap/ic_launcher" Android:label="@string/app_name" Android:supportsRtl="true" Android:theme="@style/AppTheme">

(2)定義具體的AppTheme樣式

其中這裏的windowAnimationStyle就是咱們定義Activity切換動畫的style。而@anim/slide_in_top就是咱們定義的動畫文件,也就是說經過爲Appliation設置style,而後爲windowAnimationStyle設置動畫文件就能夠全局的爲Activity的跳轉配置動畫效果。

<!-- Base application theme. --> 
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="Android:windowAnimationStyle">@style/activityAnim</item>
</style><!-- 使用style方式定義activity切換動畫 --> <style name="activityAnim"> <item name="Android:activityOpenEnterAnimation">@anim/slide_in_top</item> <item name="Android:activityOpenExitAnimation">@anim/slide_in_top</item> </style>

而在windowAnimationStyle中存在四種動畫:

  • activityOpenEnterAnimation
    用於設置打開新的Activity並進入新的Activity展現的動畫
  • activityOpenExitAnimation
    用於設置打開新的Activity並銷燬以前的Activity展現的動畫
  • activityCloseEnterAnimation
    用於設置關閉當前Activity進入上一個Activity展現的動畫
  • activityCloseExitAnimation
    用於設置關閉當前Activity時展現的動畫

3.使用ActivityOptions切換動畫實現Activity跳轉動畫

經過overridePendingTransition方法基本上能夠知足咱們平常中對Activity跳轉動畫的需求了,但MD風格出來以後,overridePendingTransition這種老舊、生硬的方式怎麼能適合咱們的MD風格的App呢?google在新的sdk中給咱們提供了另一種Activity的過分動畫——ActivityOptions。而且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat是一個靜態類,提供了相應的Activity跳轉動畫效果,經過其能夠實現很多炫酷的動畫效果。

(1)在跳轉的Activity中設置contentFeature

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 設置contentFeature,可以使用切換動畫 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); Transition explode = TransitionInflater.from(this).inflateTransition(Android.R.transition.explode); getWindow().setEnterTransition(explode); setContentView(R.layout.activity_three); }

(2)在startActivity執行跳轉邏輯的時候調用startActivity的重寫方法,執行ActivityOptions.makeSceneTransitionAnimation方法

/** * 點擊按鈕,實現Activity的跳轉操做 * 經過Android5.0及以上代碼的方式實現activity的跳轉動畫 */
button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, ThreeActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle()); } });

activity跳轉動畫效果

(四)使用ActivityOptions以後內置的動畫效果經過style的方式

這種方式其實就是經過style的方式展現和使用ActivityOptions過分動畫,下面是實現經過定義style方式定義過分動畫的步驟:

(1)編寫過分動畫文件

<explode xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:duration="300" />

首先咱們須要在Application項目res目錄下新建一個transition目錄,而後建立資源文件,而後使用這些系統自帶的過渡動畫效果,這裏設置了過分時長爲300ms。

(2)定義style文件

<!-- Base application theme. --> 
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="Android:windowEnterTransition">@transition/activity_explode</item> <item name="Android:windowExitTransition">@transition/activity_explode</item> </style>

在Application的style文件中添加:

<item name="Android:windowEnterTransition">@transition/activity_explode</item> <item name="Android:windowExitTransition">@transition/activity_explode</item>

並指定過渡動畫效果爲咱們剛剛定義的過渡動畫文件。

(3)執行跳轉邏輯

點擊按鈕,實現Activity的跳轉操做 * 經過Android5.0及以上style的方式實現activity的跳轉動畫

button4.setOnClickListener(new View.OnClickListener() 
{ @Override public void onClick(View v) { /** * 調用ActivityOptions.makeSceneTransitionAnimation實現過分動畫 */ Intent intent = new Intent(MainActivity.this, FourActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle()); } });

這樣執行以後也能夠展現出Activity跳轉過分動畫了,其和經過代碼方式實現的效果是相似的,並且這種動畫效果是全局的。

(五)使用ActivityOptions動畫共享組件的方式實現跳轉Activity動畫

這裏的共享組件動畫效果是指將前面一個Activity的某個子View與後面一個Activity的某個子View之間有過渡效果,即在這種過分效果下實現Activity的跳轉操做。那麼如何實現兩個組件View之間實現過渡效果呢?

(1)定義共享組件

在Activity a中的button按鈕點擊transitionName屬性:

<Button Android:id="@+id/button5" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_below="@+id/button4" Android:layout_marginTop="10dp" Android:layout_marginRight="10dp" Android:layout_marginLeft="10dp" Android:text="組件過分動畫" Android:background="@color/colorPrimary" Android:transitionName="shareNames" />

在Activity b的佈局文件中爲組件定義transitionName屬性,這樣這兩個組件至關於有了過分對應關係,這裏須要注意的是這兩個組件的transitionName屬性的值必須是相同的。

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:id="@+id/activity_second" Android:layout_width="match_parent" Android:layout_height="match_parent" Android:gravity="center_horizontal" Android:orientation="vertical" Android:transitionName="shareNames" > <TextView Android:layout_width="match_parent" Android:layout_height="match_parent" Android:background="@color/colorAccent" Android:layout_marginTop="10dp" Android:layout_marginBottom="10dp" /> </LinearLayout>

(2)調用startActivity執行跳轉動畫

點擊按鈕,實現Activity的跳轉操做 * 經過Android5.0及以上共享組件的方式實現activity的跳轉動畫

button5.setOnClickListener(new View.OnClickListener() { 
@Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, FiveActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, button5, "shareNames").toBundle()); } });

須要說明的是這裏調用的ActivityOptions.makeSceneTransitionAnimation方法,傳遞了三個參數,其中第一個參數爲context對象,第二個參數爲啓動Activity的共享組件,第三個參數爲啓動Activity的共享組件transitionName屬性值。

這樣通過調用以後咱們就實現了從Activity a跳轉到Activity b的時候a中的組件到b中組件的過分效果。

過渡動畫總結

  • overridePendingTransition方法從Android2.0開始,基本上可以覆蓋咱們activity跳轉動畫的需求;
  • ActivityOptions API是在Android5.0開始的,能夠實現一些炫酷的動畫效果,更加符合MD風格;ActivityOptions還能夠實現兩個Activity組件之間的過分動畫;
    過渡動畫可參考github項目地址:實現activity跳轉動畫的五種方式
相關文章
相關標籤/搜索