Activity使用總結

作為Android入門級別的組件,Activity在Android的開發中承載瞭太多的東西,我們的項目開發中少不瞭與Activity打交道。所以需要我們熟練掌握Activity的使用。

總體介紹圍繞下面的幾個議題進行討論,以前也總結過Activity的特點,那時候剛學習Android總結的也過於死板,這次準備集中把Android知識進行梳理一下,所以比較有總結性。

Activity的使用。 Activity的模式。 Activity的通訊. Activity的管理。 Activity常見問題:
從一個應用打開另一個應用。 完全退出應用。 動畫切換 從另一個頁面回調數據。

一、Activity基本使用

在項目的開發中,Activity承載瞭我們的頁面展示,它通過setContentView(int Id)方法綁定顯示的佈局,然後進行顯示。Activity的基本使用。

1、Activity的定義聲明

(1)、繼承Activity,實現Activity的生命周期方法。

  public class MainActivity extends Activity {
       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
       }

       @Override
       protected void onStart() {
           super.onStart();
           Log.d(TAG, "onStart");
       }

       @Override
       protected void onStop() {
           super.onStop();
           Log.d(TAG, "onStop");
       }

       @Override
       protected void onResume() {
           super.onResume();
           Log.d(TAG, "onResume");
       }

       @Override
       protected void onPause() {
           super.onPause();
           Log.d(TAG, "onPause");
       }

       @Override
       protected void onDestroy() {
           super.onDestroy();
           Log.d(TAG, "onDestroy");
       }
   }

(2)、在Manifest.xml清單文件中註冊Activity。四大組件在使用的時候都必須在清單文件中進行列舉。

    
        
            

            
        
    

2、Activity的跳轉

我們知道Activity承載瞭我們應用幾乎全部的頁面顯示工作,那麼我們如何進行頁面之前的跳轉呢?這裡就需要使用Intent類進行頁面的跳轉。

顯示跳轉,針對我們在同一個應用中知道跳轉頁面的名字。

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

隱式跳轉,當我們不知道一個應用的類名,隻知道action、category屬性時,進行使用:

 Intent loginIntent = new Intent();
 loginIntent.setAction("com.intent.action.LOGIN");
 loginIntent.addCategory("com.intent.category.LOGIN");
 startActivity(loginIntent);

註意,這裡的action和category要和聲明的Activity在清單文件中註冊的保持一致。隱式Intent通過Android解析,將Intent映射給可以處理此Intent的Activity、IntentReceiver或Service。

Intent解析機制主要是通過查找已註冊在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。

在這個解析過程中,Android是通過Intent的action、type、category這三個屬性來進行判斷的,判斷方法如下:

如果Intent指明定瞭action,則目標組件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配; 如果Intent沒有提供type,系統將從data中得到數據類型。和action一樣,目標組件的數據類型列表中必須包含Intent的數據類型,否則不能匹配。 如果Intent中的數據不是content: 類型的URI,而且Intent也沒有明確指定它的type,將根據Intent中數據的scheme (比如 http: 或者mailto:) 進行匹配。同上,Intent 的scheme必須出現在目標組件的scheme列表中。 如果Intent指定瞭一個或多個category,這些類別必須全部出現在組建的類別列表中。比如Intent中包含瞭兩個類別:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目標組件必須至少包含這兩個類別。 每一個通過startActivity()方法發出的隱式Intent都至少有一個category,就是 “android.intent.category.DEFAULT”,所以隻要是想接收一個隱式Intent的Activity都應括”android.intent.category.DEFAULT” category,不然將導致 Intent 匹配失敗。

我們知道Activity有許多startXXX方法,所以我們這次總結下:
– startActivity():啟動單個Activity
– startActivities(Intent[] intent,Bundle options):直接跳到最後一個Intent對應的頁面,當點擊返回鍵的時候,會逐個返回。常見常見:我們從主頁點擊產品進到某個產品的詳情頁面,然後返回鍵返回到產品列表頁面。就可以使用這個。
– startActivityIfNeeded()當啟動的Activity設置瞭singleTop、singleTask時並且request Code小於0時不啟動。
– startActivityForResult():啟動一個你想數據回調的頁面,當頁面存在的時候,回調數據到onActivityResult方法中。

3、Activity的生命周期

onCreate():啟動創建Activity,系統第一個執行的方法。 onStart():就在(just before)Activity成為可見之前調用 onRestart():Activity從後臺重新回到前臺時被調用,用戶可見但不可交互 onResume():就在(just before)Activity開始與用戶交互之前調用。(此時不能完全交互) onWindowFocusChanged():Activity窗口獲得或失去焦點時被調用,在onResume之後或onPause之後 onPause():Activity被覆蓋到下面或者鎖屏時被調用 onStop():退出當前Activity或者跳轉到新Activity時被調用 onDestroy():退出當前Activity時被調用,調用之後Activity就結束瞭 onSaveInstanceState(Bundle outState):Activity被系統殺死時被調用. 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處於後臺,系統資源緊張將其殺死. 另外,當跳轉到其他Activity或者按Home鍵回到主屏時該方法也會被調用,系統是為瞭保存當前View組件的狀態.
在onPause之前被調用. onRestoreInstanceState(Bundle savedInstanceState):Activity被系統殺死後再重建時被調用.例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處於後臺,系統資源緊張將其殺死,用戶又啟動該Activity.這兩種情況下onRestoreInstanceState都會被調用,在onStart之後。

在Activity的生命周期中,我們經常討論的前臺生命周期(onResume——onPause),可視聲明周期,這裡我們很少談論真正在哪個階段我們是可以與界面交互的。我們都知道在onCreate()方法中對一個View進行getHeight()、getWidth()會獲取空值,為什麼呢?這是因為此時的View還沒有進行寬高的測量,在Activity的生命周期中,真正使我們開始於Activity交互的周期在 onWindowFocusChanged()中,我們可以獲取控件的高度和寬度。站在Window視圖的角度來看,Activity的生命周期又可具體到:

entry: onStart—->onResume—->onAttachedToWindow———–>onWindowVisibilityChanged–visibility=0———->onWindowFocusChanged(true)——-> exit: onPause—->onStop—->onWindowFocusChanged(false) ———————- (lockscreen) exit : onPause—–>onWindowFocusChanged(false)——–>onWindowVisibilityChanged–visibility=8————>onStop(to another activity)

4、Activity的基本模式

在Android開發中,Activity有四種模式,我們可以在Manifest.xml文件中註冊時進行設置:

  

這裡,我們需要補充一點知識,關於Activity的管理方式,這裡是借助棧類型數據結構進行管理,所以這四種模式分別對應瞭Activity的四種管理方式:

standard:標準默認模式,每次創建一個Activity都會創建一個對應的實例。 singleTop:可以有多個實例,如果Activity在棧頂的時候,啟動相同的Activity,不會創建新的實例,而會調用其onNewIntent方法。 singleTask:隻有一個實例。在同一個應用程序中啟動他的時候,若Activity不存在,則會在當前task創建一個新的實例,若存在,則會把task中在其之上的其它Activity destory掉並調用它的onNewIntent方法。 singleInstance:隻有一個實例,並且這個實例獨立運行在一個task中,這個task隻有這個實例,不允許有別的Activity存在。

合理運用這四種模式,能夠使應用的體驗和資源使用率更好。比如:singleTask適合作為程序入口點,因為app的入口點就一個。singleInstance適合需要與程序分離開的頁面,例如鬧鈴提醒,將鬧鈴提醒與鬧鈴設置分離。

5、Activity的通訊數據傳遞

在同一個進程中的Activity之間少不瞭交互,那麼Activity之間怎麼進行數據的交互呢?

Intent承載傳遞數據 廣播 第三方通訊組件

這裡,我們主要介紹下前兩種的使用,後兩種以後再介紹。
(1)、Intent傳遞數據
在Android中提供瞭Intent機制來協助應用間的交互與通訊,Intent負責對應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android則根據此Intent的描述,負責找到對應的組件,將 Intent傳遞給調用的組件,並完成組件的調用。Intent有六大屬性值需要註意:

Action:用於指定我們要完成的動作,是一個字符串常量。當然我們在註冊四大組件時也可以指定對應的action值。系統也有些自帶的:ACTION_CALL、ACTION_MAIN。通過setAction()方法進行設置。 Data:Intent的Data屬性是執行動作的URI和MIME類型,不同的Action有不同的Data數據指定。比如:ACTION_EDIT Action應該和要編輯的文檔URI Data匹配,ACTION_VIEW應用應該和要顯示的URI匹配。通過setData()方法進行設置。 Category:Intent中的Category屬性是一個執行動作Action的附加信息。比如:CATEGORY_HOME則表示放回到Home界面,ALTERNATIVE_CATEGORY表示當前的Intent是一系列的可選動作中的一個。通過addCategory()進行設置。 Type:Intent的Type屬性顯式指定Intent的數據類型(MIME)。一般Intent的數據類型能夠根據數據本身進行判定,但是通過設置這個屬性,可以強制采用顯式指定的類型而不再進行推導。通過setType()方法進行設置。 Compent:Intent的Compent屬性指定Intent的的目標組件的類名稱。通常 Android會根據Intent 中包含的其它屬性的信息,比如action、data/type、category進行查找,最終找到一個與之匹配的目標組件。但是,如果 component這個屬性有指定的話,將直接使用它指定的組件,而不再執行上述查找過程。指定瞭這個屬性以後,Intent的其它所有屬性都是可選的。(很重要,比如我們在一個應用啟動另一個應用)。通過setComponent(ComponentName)方法進行設置。 Extra:Intent的Extra屬性是添加一些組件的附加信息。比如,如果我們要通過一個Activity來發送一個Email,就可以通過Extra屬性來添加subject和body。通過putExtra()方法進行設置。

在上面的介紹中,我們可以發現Intent超級強大的用途,可用於啟動組件,也可以用於傳遞數據,所以Intent的設計就是為瞭在組件之間進行“溝通”傳遞使用。在啟動Activity的時候,我們可以使用putExtra方法進行設置數據。然後傳遞到跳轉到的頁面。

二、Activity常見場景

- 從一個應用打開另一個應用。
- 完全退出應用。
- 動畫切換
- 從另一個頁面回調數據。

1、從一個應用啟動另一個應用

這裡,我們使用Intent的setComponent方法來設置啟動的頁面。通過建立ComponentName對象來實現。

Intent loginIntent = new Intent();
ComponentName componentName = new ComponentName("com.dsw.pluginapp","com.dsw.pluginapp.MainActivity");
loginIntent.setComponent(componentName);
startActivity(loginIntent);

3、從跳轉頁面回調數據

在Android的頁面之間,經常有數據回調,這個時候我們就可以采用startActivityForResult方法啟動Activity,然後使用onActivityResult進行回調。
啟動Activity

 Intent loginIntent = new Intent();
ComponentName componentName = new ComponentName(getApplicationContext(),"com.iflytek.testandroid.LoginActivity");
loginIntent.setComponent(componentName);
startActivityForResult(loginIntent, requstCode);

回調的處理,重寫onActivityResult方法。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == this.requstCode){
        if(resultCode == RESULT_OK){
            tv.setText(data.getStringExtra("name"));
        }
    }
}

回調數據同樣通過Intent進行封裝。

   Intent intent  = new Intent();
   intent.putExtra("name", "From LoginActivity");
   setResult(RESULT_OK, intent);
   finish();

這樣就完成瞭數據的回調。

2、Activity啟動動畫切換

在Activity的跳轉時,我們可以增加動畫效果,一種是通過設置xml配置Activity的theme進行設置。一種是通過代碼進行設置。
(1)、通過XML設置style進行設置。
首先新建一個style,設置如下屬性。

@anim/slide_in_left  
    @anim/slide_out_left  
     @anim/slide_in_right  
    @anim/slide_out_right  

然後創建theme。

@style/AnimationActivity  
    true  

最後在manifest中給activity設置theme屬性即可。

(2)、通過代碼設置。
通過代碼設置使用overridePendingTransition(id,id)進行設置。通過調用overridePendingTransition() 可以實時修改Activity的切換動畫。但需註意的是:該函數必須在調用startActivity()或者finish()後立即調用,且隻有效一次。

4、完全退出應用

我們知道,一般我們從進入到一個應用,然後操作很多頁面,我們都會遇到這樣的場景,比如:點擊進入某個頁面,然後點擊返回鍵,返回到上一個頁面,上一個頁面的數據還保存著,但是我們也可能通過多個頁面的跳轉然後又返回到主頁面,此時點擊返回鍵就退出應用。這是就利用到我們的Activity的啟動模式,一般在Activity中我們針對首頁的頁面,通過設置android:launchMode=”singleTask”即可進行解決。

發佈留言