Android應用開發-Activity

 

  Android四大組件:ActivityServiceBroadcast ReceiverContent Providerjava

  Activity是Context的子類,同時實現了Window.CallbackKeyEvent.Callback接口,能夠處理用戶與窗體交互的事件。android

 

 

建立Activity

 

  1. 定義一個XxxActivity類繼承Activity,並重寫onCreate()算法

  2. 在onCreate()中經過setContentView()加載該Activity的佈局文件數組

  3. 在清單文件中配置activity標籤,註冊這個Activity瀏覽器

    • activity標籤下若是帶有下面這部分代碼,則會在系統中多建立一個快捷圖標服務器

      <activity android:name=".MainActivity">
          <intent-filter>
              <action android:name="android.intent.action.MAIN"/>
              <category android:name="android.intent.category.LAUNCHER"/>
          </intent-filter>
      </activity>
    • 一個應用程序能夠在桌面建立多個快捷圖標。app

    • Activity的名稱、圖標能夠和應用程序的名稱、圖標不相同ide

      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"

 

Activity的跳轉

 

  Activity的跳轉須要建立Intent對象,經過設置Intent對象的參數指定要跳轉的Activity佈局

  明確指定要啓動或者觸發的目標組件(能夠是Activity,Service,BroadcastReceiver)的類名或包名的Intent,稱爲顯式Intent。經過顯式Intent實現Activity的跳轉稱爲顯式跳轉this

  隱式Intent沒有明確指定要啓動或者觸發的目標組件的類名和包名,而只是指定了一系列更爲抽象的Intent Filter的屬性(包括action,category,data等)值,而後交由系統去分析這個Intent,並幫咱們找出預啓動或觸發的目標組件。經過隱式Intent實現Activity的跳轉稱爲隱式跳轉

 

顯式跳轉

  跳轉至同一應用中的Activity

Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);// 指定當前的上下文和目標Activity的字節碼
startActivity(intent);

 

  跳轉至不一樣應用中的Activity

Intent intent = new Intent();
// 指定目標Activity所在的應用的包名和目標Activity的包名加類名,這裏啓動系統自帶的撥號器應用(針對Android 4.3)
intent.setClassName("com.android.dialer", "com.android.dialer.DialtactsActivity");
startActivity(intent);

 

隱式跳轉

  隱式意圖跳轉至打電話Activity

Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

 

  • 要讓一個Activity能夠被隱式啓動,須要在該應用清單文件下的activity標籤下配置intent-filter子標籤

  • 系統會在全部應用的清單文件中尋找與咱們建立的隱式Intent匹配的intent-filter,找到則啓動,找不到則拋異常

  • 匹配就是intent-filter中定義了什麼屬性,咱們建立的intent中也必須設置什麼屬性,而且對應的屬性值也同樣

  • 在清單文件的activity標籤下,配置intent-filter子標籤,其中再配置dataactioncategory子標籤。其中data標籤下能夠配置scheme、host、port、path等子標籤,它們構成一個android.net.Uri對象  scheme://host:port/path ,也叫URL Scheme,其應用場景大致分爲如下幾種:

    • 服務器下發跳轉路徑,app端根據服務器下發跳轉路徑跳轉相應的頁面
    • H5頁面點擊錨點,根據錨點具體跳轉路徑app端跳轉到相應的頁面
    • app端收到服務器下發的Push通知欄消息,根據消息的點擊跳轉路徑跳轉相關頁面
    • app端根據URL跳轉到另一個app的指定頁面

 

應用場景

  • 啓動同一應用中的Activity,用顯式Intent。顯式啓動效率明顯高於隱式,由於顯示直接指定了目標Activity,隱式須要遍歷全部應用的清單文件尋找匹配的Intent Filter

  • 啓動不一樣應用中的Activity,用隱式Intent。當使用隱式Intent跳轉到其餘應用中的Activity時,若是系統找到了多個intent-filter與咱們建立的Intent匹配,就會彈出對話框,列舉全部匹配的Activity,讓用戶選擇。好比咱們的手機裏若是安裝了多款瀏覽器App,當咱們點擊一個URL時,會彈出一個對話框讓咱們選擇使用哪一個瀏覽器來打開這個網頁,這就是由於跳轉到瀏覽器Activity用的是隱式Intent;有些應用的Activity啓動時須要接收數據,好比打電話Activity須要接收電話號碼,也只能用隱式Intent

 

 

Activity跳轉時的數據傳遞

 

  • Activity跳轉時,能夠把數據封裝在Intent中

    Intent intent = new Intent(this, SecondActivity.class);
    intent.putExtra("name", name); // 字符串類型
    intent.putExtra("age", age);    // 整型
    startActivity(intent);

     

  • 在跳轉到的目標Activity中取出數據

    Intent intent = getIntent();    // 獲取啓動該Activity的Intent
    String name = intent.getStringExtra("name");
    int age = intent.getIntExtra("age");

 

  • Intent中能夠封裝的數據類型:八大基本數據類型及其數組、String及其數組、實現了序列化接口Serializable和Parcelable的對象、Parcelable數組、Bundle對象(數據能夠先封裝至Bundle,再把Bundle封裝至Intent)。

 

 

Activity的生命週期

 

 

  • onCreate():建立Activity時被回調

  • onStart():在屏幕上可見,可是尚未得到焦點,用戶還不能與這個Activity進行交互(點擊、滑動等)

  • onResume():可見而且得到焦點,用戶已經能夠和這個Activity進行交互(點擊、滑動等)

  • onPause():可見,可是失去焦點。

  • onStop():徹底不可見

  • onDestroy():銷燬時調用

  • onRestart():Activity從不可見變爲可見時調用

 

  • 按Home鍵,系統依次回調onPause()onStop(),Activity進入中止狀態,進程還在(後臺進程);若再次進入該Activity,系統會依次回調onRestart()onStart()onResume(),Activity從新進入運行狀態

  • 按Back鍵,系統依次回調onPause()onStop()onDestroy(),Activity被銷燬,進程還在(空進程);若再次進入該Activity,系統會依次回調onCreate()onStart()onResume(),Activity從新進入運行狀態

    • 按返回鍵,Android系統會回調onBackPressed()方法,該方法調用了finish(),因此Activity會被銷燬
  • 當另外一個優先級更高的進程須要內存而手機內存不足時,Android系統纔會殺死以前啓動的進程,按照進程優先級和LRU算法(優先級相同時)決定殺死哪一個進程。

  • 用戶也能夠到應用管理界面手動殺死某個進程。

 

 

Activity的四種啓動模式

 

  Task是咱們在執行某種工做時所交互的activity的集合,這些activity集合按照打開的順序被放置在同一個棧中,這個棧叫做Back Stack,Activity的啓動模式決定了Back Stack的操做規則,對於啓動同一應用中的Activity(啓動其餘應用中的Activity,四種啓動模式的表現形式略微複雜,後續探討),四種啓動模式的表現以下:

 

  • standard:默認模式,每次發送一個Intent啓動standard模式的Activity時,Android總會爲目標Activity建立一個新的實例,並將該Activity實例添加到啓動它的Activity所在的Task棧的棧頂

  • singleTop:Task棧頂單例模式,與標準模式僅有一點不一樣:當啓動的目標Activity已經位於當前Activity所在Task棧的棧頂時,Intent不會再建立一個目標Activity實例(複用已有的Activity實例,不會觸發onCreate()),而是經過onNewIntent()被髮送到現有的Activity

    • 應用:瀏覽器書籤歷史記錄界面CombinedBookmarkHistoryActivity
    • 應用:短信會話記錄界面ConversationList
  • singleTask:採用這種啓動模式的Activity在整個Android系統內存中只能有一個實例。對於啓動同一個應用中的Activity,若是系統內不存在將要啓動的目標Activity,系統將會建立目標Activity的實例,並將它壓入當前Task棧頂;若是已經存在該Activity的實例,系統會將該Activity所在Task移至前臺(多半是已經在前臺),再退棧至該Activity,同時也會經過onNewIntent()將Intent發送到該Activity。對於啓動不一樣應用中的Activity,若是系統內不存在將要啓動的目標Activity,系統會建立一個新的Task,再建立出目標Activity的實例入棧;若是已經存在該Activity的實例,表現同啓動同一應用中的Activity一致

    • 應用:瀏覽器瀏覽界面BrowserActivity
  • singleInstance:採用這種啓動模式的Activity在整個Android系統內存中也只能有一個實例,且老是獨佔一個Task,任何被此Activity啓動的Activity都會被放到其它的task中。若是目標Activity不存在,系統會先建立一個新的Task,再建立目標Activity的實例壓入棧頂;若是將要啓動的目標Activity已經存在,不管它位於哪一個應用程序中、位於哪一個Task中,系統都會把該Activity所在的Task轉到前臺,從而使該Activity顯示出來

    • 應用:來電界面InCallScreen

 

 

Activity的橫豎屏切換

 

  • 默認狀況橫豎屏切換會使Activity銷燬重建,觸發生命週期方法從新執行

  • 在一些特殊的應用程序中,好比遊戲,不但願橫豎屏切換致使Activity被銷燬重建,由於若是不保存會丟失遊戲數據

    • 在清單文件中用如下代碼讓橫豎屏切換時不重建Activity

      android:configChanges="orientation|screenSize|keyboardHidden"

       

    • 在清單文件中可用如下代碼寫死Activity的屏幕方向

      android:screenOrientation="portrait"     <!-- 豎屏 -->
      android:screenOrientation="landscape"    <!-- 橫屏 -->

       

    • 在java文件中可用如下代碼寫死Activity的屏幕方向(會覆蓋清單文件中設置的屏幕方向,由於後執行)

      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  // 豎屏
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 橫屏

       

 

Activity銷燬時返回數據

 

步驟

 

  • 指定請求碼requestCode啓動新的Activity

    Intent intent = new Intent(this, SecondActivity.class);
    startActivityForResult(intent, requestCode);// 只有用這種方式啓動的Activity在銷燬時纔會回調原Activity的onActivityResult()方法

 

  • 在新的Activity中設置要返回的數據

    Intent intent = new Intent();  // 該意圖僅用來攜帶數據
    intent.putExtra("tel", tel);
    setResult(resultCode, intent); // 指定一個結果碼resultCode,並把數據會返回給原Activity
    finish();                     // 銷燬當前的Activity

 

  • 在原Activity裏面實現方法

    // 經過intent獲取返回的數據
    onActivityResult(int requestCode, int resultCode, Intent intent) {
    
    }

 

  • 經過判斷請求碼和結果碼肯定返回的Intent的做用

    • 先經過請求碼requestCode判斷返回的Intent來自哪個Activity

    • 再經過該Activity返回的結果碼resultCode來判斷Intent所攜帶的是該Activity返回的哪個數據

相關文章
相關標籤/搜索