Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android資訊 >> 作為Android開發者,你真的熟悉Activity嗎?

作為Android開發者,你真的熟悉Activity嗎?

編輯:Android資訊

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

一、 activity的生命周期

正常生命周期

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

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

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

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

注意:B這個Activity是在A的onPause執行後才變成可見狀態的,所以為了不影響B的顯示,最好不要在onPause裡執行一些耗時操作,可以考慮將這些操作放到onStop裡,這時B已經可見了。

異常情況生命周期

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

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

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

Activity優先級

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

二、activity的啟動模式

四種啟動模式分別是standard(標准模式)、singleTop(棧頂復用模式)、singleTask(棧內復用模式)、singleInstance(單實例模式 – 加強的singleTask模式)

standard

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

singleTop

  • 判斷需要啟動的Activity是否為任務棧棧頂 ,如果是,則不會重新創建,如果不是,則會重新創建
  • 不重新創建時候,該Activity的 onNewIntent(Intent intent) 方法會被回調,通過該方法的參數,可以取出當前請求的信息;
  • 系統可能會殺死該Activity,殺死之後,啟動情況與第一次啟動相同,所以有必要在onCreate與onNewIntent方法中調用同一個處理數據的方法

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

singleTask

  • 判斷Activity所需任務棧內是否已經存在,如果存在,就把該Activity切換到棧頂(會導致在它之上的都會出棧)
  • 如果所需任務棧都不存在,就會先創建任務棧再創建該Activity
  • 可以理解為 頂置Activity+singleTop 的模式

    運用場景:可用來退出整個應用。主界面activity設為singleTas模式,要退出應用時轉到主activity,從而將主activity之上的activity都清除,然後重寫主activity的onNewIntent()方法,在裡面加上finish(),即可退出所有activity。這種模式還適用於做浏覽器、微博之類的應用

singleInstance

  • 擁有singleTask的所有特性之外,此模式Activity只能單獨地位於一個新的任務棧中
  • 也就是,Activity啟動之後,就會獨自在一個新的任務棧中,下次肯定不會重新創建該Activity,除非被系統殺死

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

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

1、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:[email protected];[email protected]");
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);

四、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方法立刻執行才有效

2、使用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跳轉動畫的五種方式
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved