Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 四大組件之Activity(下)——Activity的常用Manifest屬性、啟動模式、ADB調試

四大組件之Activity(下)——Activity的常用Manifest屬性、啟動模式、ADB調試

編輯:關於Android編程

第5節 Activity的Manifest配置

5.1 Activity的聲明

Activity作為四大組件,代碼中每定義一個Activity就需要在AndroidManifest.xml文件中聲明它。

<code class="language-xml hljs "><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anddle.activitytest">

    <application android:icon="@mipmap/ic_launcher" android:label="@string/app_name">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN">
                <category android:name="android.intent.category.LAUNCHER">
            </category></action></intent-filter>
        </activity>

        <activity android:name=".AlertActivity" android:theme="@android:style/Theme.Dialog">
        </activity>
    </application>

</manifest></code>

5.2 Activity標簽常用屬性

Activity標簽還有一些我們常用到的屬性。

這裡的intent-filter標簽內指定的內容表示:這個Activity可以作為這個應用程序的入口。

<code class="language-xml hljs "><activity android:name=".MainActivity">
    <intent-filter> 
        <action android:name="android.intent.action.MAIN">
        <category android:name="android.intent.category.LAUNCHER">
    </category></action></intent-filter>
</activity></code>

直觀一點,就是說它可以被放在桌面上,供用戶通過點擊直接進入。假如一個應用有三個這樣的Activity,那麼桌面上將有三個圖標,供用戶點擊啟動。

指定Activity的主題。安卓系統為界面元素設計了幾種不同的顯示風格,叫做主題。關於主題的詳細介紹我們將放在以後的章節。


    android:theme="@android:style/Theme.Dialog">

指定Activity的啟動方式。啟動方式在下一小節詳細講述。


    android:launchMode="standard">

指定Activity是否關注系統配置的變化,


    android:configChanges="screenSize|orientation">

響應特定的Action,遇到這樣的Action就可以啟動該Activity,


   
       
   

那麼,啟動該Activity的代碼,就可以通過它配置中的Action

Intent i = new Intent("android.intent.action.VIEW");
startActivity(i);

除了以上列出的一些屬性外,Activity的很多特性都可以這樣設置。

第6節 Activity啟動模式

Activity的啟動模式,就是指當用戶或者系統啟動一個Activity時,將這個Activity如何放到Task中進行管理。


   android:launchMode="standard">

Activity有四種啟動方式:standard、singleTop、singleTask、singleInstance。

6.1 standard模式

這是每個Activity默認的啟動模式,如果我們沒有在manifest中指定,那麼Activity啟動就會采用這個模式。這個模式很簡單,原則只有一個:當啟動這種類型的Activity時,只要重新創建,然後放在Task棧的棧頂就好了。

進一步舉個例子:Activity A上,有一個按鈕,點擊後,可以再啟動一個Activity A。這時我們看到的Task堆棧情況就是,Activity A上又創建了一個Activity A。這兩個Activity都是Activity A的實例,是互相獨立的Activity,在內存中有各自的一塊區域。

開發者官網1

6.2 singleTop模式

這個啟動模式的原則是:當啟動這個類型的Activity時,如果這個Activity有實例在當前Task中存在,並且位於這個Task的棧頂,那麼就調用onNewIntent()通知一下,而不用重新創建;

開發者官網1

否則,即使這個Task中有這個Activity實例,只要它不在棧頂,就重新創建;

開發者官網1

使用場景:一個新聞客戶端會接收新聞推送,在statusbar上顯示已經收到10條推送了。當我們點擊第一條的時候,啟動一個顯示新聞內容的Activity-ContentActivity,當我們點擊statusbar上的第二條新聞時,再次啟動ContentActivity。如果ContentActivity是standard模式,可以想見,在之前的新聞內容上,又回彈出一個Activity,10條推送點擊十次,就會有10個Activity疊在一起。

麻煩的是返回時得按10次,而且會占用很多系統資源。

如果將ContentActivity指定為singleTop,那麼點擊後面9條推送時,ContentActivity只會通過onNewIntent()知道有新的調用請求,不必重新創建9個Activity實例過份消耗資源。

6.3 singleTask模式

這個啟動模式的原則是:當啟動這個類型的Activity時,先查看這個Activity是否有實例在系統當前的Task中存在。

6.3.1 前台Task中存在

如果它在位於前台的task中存在,並且位於這個Task的棧頂,那麼就調用onNewIntent()通知一下,而不用重新創建--這一點與singleTop模式類似;

開發者官網1

如果存在,但是不在Task的棧頂,就將這個Activity上面別的Activity全部彈出、銷毀,把這個Activity的實例放到最上面,再用onNewIntent()通知它一次。

開發者官網1

6.3.2 後台Task中存在

如果它在位於後台的task中存在,就把後台task放到前台來,然後把它上面存在的別的Activity彈出、銷毀。

開發者官網1

使用場景:應用的主Activity A,可以啟動Activity B, Activity B又能啟動Activity C,C又能啟動D,設計者希望從D能夠直接返回到主Activity。

對於這種希望在任意層級的Activity下,快速返回到主界面的應用,就可以把主Activity A設置成singleTask模式。

6.4 singleInstance模式

這個啟動模式的原則是:當啟動這個類型的Activity時,如果該Activity之前並不存在,就會重新創建一個Task,並把該Activity放入其中。假如這個Activity要啟動別的Activity-C,那麼就放在之前那個Task之上。

開發者官網1

如果該Activity已經存在,就把該Activity所在的task切換到前台來。
總之,一個task中有且只有一個這種類型的Activity。

開發者官網1

使用場景:對於那種需要提供給第三方調用的Activity,例如微信的分享、轉發,就可以把這種Activity設置成singgleInstance。這樣在系統范圍內保證只有一個這樣的Activity存在。

第7節 ADB工具調試Activity

為了幫助我們深入學習Activity,這裡介紹通過ADB工具獲取系統中現有Activity信息的方法。

7.1 打印系統Activity信息

用命令行工具進入adb所在的目錄,
輸入adb shell dumpsys activity activities,會輸出類似如下的內容:

$ ./adb shell dumpsys activity activities

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #0:
    Task id #178
    * TaskRecord{cce8184 #178 I=com.android.launcher3/.Launcher U=0 sz=1}
      userId=0 effectiveUid=u0a8 mCallingUid=0 mCallingPackage=null
      intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher3/.Launcher}
      realActivity=com.android.launcher3/.Launcher
      autoRemoveRecents=false isPersistable=true numFullscreen=1 taskType=1 mTaskToReturnTo=0
      rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
      Activities=[ActivityRecord{b820c49 u0 com.android.launcher3/.Launcher t178}]
      askedCompatMode=false inRecents=true isAvailable=true
      lastThumbnail=null lastThumbnailFile=/data/system/recent_images/178_task_thumbnail.png
      stackId=0
      hasBeenVisible=true mResizeable=false firstActiveTime=1451983947131 lastActiveTime=1451983947131 (inactive for 2501s)
      * Hist #0: ActivityRecord{b820c49 u0 com.android.launcher3/.Launcher t178}
          packageName=com.android.launcher3 processName=com.android.launcher3
          launchedFromUid=0 launchedFromPackage=null userId=0
          app=ProcessRecord{f7b8d6d 25040:com.android.launcher3/u0a8}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher3/.Launcher }
          frontOfTask=true task=TaskRecord{cce8184 #178 I=com.android.launcher3/.Launcher U=0 sz=1}
          taskAffinity=null
          realActivity=com.android.launcher3/.Launcher
          baseDir=/system/priv-app/Launcher3/Launcher3.apk
          dataDir=/data/user/0/com.android.launcher3
          stateNotNeeded=true componentSpecified=false mActivityType=1
          compat={420dpi} labelRes=0x7f0c0005 icon=0x7f030000 theme=0x7f0e000e
          config={1.0 310mcc260mnc zh_CN ldltr sw411dp w411dp h659dp 420dpi nrml port finger qwerty/v/v dpad/v s.6}
          stackConfigOverride={1.0 ?mcc?mnc ?locale ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/?}
          taskDescription: iconFilename=null label="null" color=ff212121
          launchFailed=false launchCount=1 lastLaunchTime=-41m41s66ms
          haveState=false icicle=null
          state=RESUMED stopped=false delayedResume=false finishing=false
          keysPaused=false inHistory=true visible=true sleeping=false idle=true
          fullscreen=true noDisplay=false immersive=false launchMode=2
          frozenBeforeDestroy=false forceNewConfig=false
          mActivityType=HOME_ACTIVITY_TYPE
          waitingVisible=false nowVisible=true lastVisibleTime=-41m39s31ms

    Running activities (most recent first):
      TaskRecord{cce8184 #178 I=com.android.launcher3/.Launcher U=0 sz=1}
        Run #0: ActivityRecord{b820c49 u0 com.android.launcher3/.Launcher t178}

    mResumedActivity: ActivityRecord{b820c49 u0 com.android.launcher3/.Launcher t178}

  mFocusedActivity: ActivityRecord{b820c49 u0 com.android.launcher3/.Launcher t178}
  mFocusedStack=ActivityStack{c009da2 stackId=0, 1 tasks} mLastFocusedStack=ActivityStack{c009da2 stackId=0, 1 tasks}
  mSleepTimeout=false
  mCurTaskId=178
  mUserStackInFront={}
  mActivityContainers={0=ActivtyContainer{0}A}
  mLockTaskModeState=NONE mLockTaskPackages (userId:packages)=
    0:[]
 mLockTaskModeTasks[]

它記錄下了當前安卓系統中所有的Task,以及每個Task中包含的Activity信息。

例如這裡記錄了,

系統中有一個Task id#178Task; Task棧中的Activity,從上到下依次是TaskRecord---com.android.launcher3/.Launcher,一個Activity; 並且com.android.launcher3/.Launcher這個Activity是位於前台的Activity

這些信息對程序的調試會有很大的幫助。

7.2 ADB啟動Activity

用ADB工具啟動已知Activity,

$ ./adb shell am start -n 包名/包名.activity名稱}

這裡的包名就形如:com.android.launcher3,例如

$ ./adb shell am start -n com.android.launcher3/com.android.launcher3.Launcher}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved