Activity那些事(一)

文章目录

      • Activity生命周期
      • 启动模式与属性
      • Activity启动方式

Activity生命周期

Activity那些事(一)_第1张图片

  1. Launcher 启动 Activity
    Activity那些事(一)_第2张图片
  2. Activity A 启动 B
    Activity那些事(一)_第3张图片
    如果Activity_B是透明的,则Activity_A不会执行onStop方法,Activity_B返回时,Activity_A直接调用onResume,回到前台。
    如果Activity_B不是是透明的,Activity_A设置了属性:android:noHistory=“true”,则Activity_A不会执行onStop方法,Activity_B返回时,Activity_A直接调用onStop->onDestroy。

设置Activity为透明

    

启动模式与属性

  1. Activity栈简介

一个ActivityRecord对应一个Activity,一个Activity可能对应多个ActivityRecord,这与Activity的启动模式有关。
Activity那些事(一)_第4张图片
使用adb shell dumpsys activity activities查看Activity栈信息

Stack #42: type=standard mode=fullscreen
    * TaskRecord{ee49cfc #50 A=com.android.activitydemonstration U=0 StackId=42 sz=2}
      affinity=com.android.activitydemonstration
      intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.activitydemonstration/.ActivityA}
      Activities=[ActivityRecord{2e0e9ef u0 com.android.activitydemonstration/.ActivityA t50}, ActivityRecord{305057 u0 com.android.activitydemonstration/.ActivityB t50}]
      stackId=42
      * Hist #1: ActivityRecord{305057 u0 com.android.activitydemonstration/.ActivityB t50}
          Intent { cmp=com.android.activitydemonstration/.ActivityB }
          taskAffinity=com.android.activitydemonstration
          state=RESUMED stopped=false delayedResume=false finishing=false
      * Hist #0: ActivityRecord{2e0e9ef u0 com.android.activitydemonstration/.ActivityA t50}
          packageName=com.android.activitydemonstration processName=com.android.activitydemonstration
          launchedFromUid=10068 launchedFromPackage=com.huawei.android.launcher userId=0
          app=ProcessRecord{2c0a3f5 1590:com.android.activitydemonstration/u0a155}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.activitydemonstration/.ActivityA bnds=[798,1694][1050,2008] }
          taskAffinity=com.android.activitydemonstration
      TaskRecord{ee49cfc #50 A=com.android.activitydemonstration U=0 StackId=42 sz=2}
        Run #1: ActivityRecord{305057 u0 com.android.activitydemonstration/.ActivityB t50}
        Run #0: ActivityRecord{2e0e9ef u0 com.android.activitydemonstration/.ActivityA t50}
    mResumedActivity: ActivityRecord{305057 u0 com.android.activitydemonstration/.ActivityB t50}
    mLastPausedActivity: ActivityRecord{2e0e9ef u0 com.android.activitydemonstration/.ActivityA t50}
  1. Activity属性
属性 取值 说明
taskAffinity 包名格式的字符串(如:.xxx) activity的亲属关系, 默认为APP的包名
launchMode standard 默认启动模式;A启动B,每次启动都会在A的Task中新建一个B。
singleTop A启动B,B的启动模式为singleTop,启动流程如下所示。Activity那些事(一)_第5张图片复用B时,B在onResume前执行noNewIntent。
singleTask Activity A启动Activity B ,B的启动模式为singleTask,如果B的taskAffinity与A的不同,则寻找与B的taskAffinity相同的Task启动B;如果相同则在A的Task中启动B。流程图如下所示。Activity那些事(一)_第6张图片如果B设置了新的taskAffinity,则这个栈会加到最近启动列表中。
singleInstance A启动Activity B ,B的启动模式为singleInstance,新建一个与B的taskAffinity相同的Task启动B,而且这个Task中有且只有B这一个Activity。重复启动B则复用B,复用B时,B在onResume前执行noNewIntent。
clearTaskOnLaunch true/false A启动B, 然后返回Home, 从新启动 B,如果A设置了这个属性为true,则不显示B,否则显示B
configChanges mcc 国际移动用户识别码所属国家代号是改变了,sim被侦测到了,去更新mcc MCC是移动用户所属国家代号
mnc 国际移动用户识别码的移动网号码是改变了, sim被侦测到了,去更新mnc MNC是移动网号码,最多由两位数字组成,用于识别移动用户所归属的移动通信网
locale 用户所在区域发生变化,一般是用户切换了语言时,切换后的语言会显示出来
touchscreen 触摸屏改变了(通常是不会发生的)
keyboard 键盘发生了改变(例如用户用了外部的键盘)
keyboardHidden 键盘的可用性发生了改变
navigation 导航发生了变化(通常不会发生)
orientation 屏幕方向改变了(横竖屏切换)
fontScale 字体比例发生了变化(选择了不同的全局字体)
screenSize 屏幕大小改变了
screenLayout 屏幕的显示发生了变化(不同的显示被激活)
注:Android 4.0之前,设置"orientation keyboardHidden"起作用,Android 4.0之后,除了设置"orientation",还必须设置"keyboardHidden orientation screenSize"
enabled true/false activity 是否可以被实例化
excludeFromRecents true/false 是否可被显示在最近打开的activity列表里(true不显示,false显示,只有栈的根Activity设置该属性才生效)。
exported true/false 是否允许activity被其它程序调用
permission 权限名称 设置启动这个Activity所需要的权限。
process 进程名称 一个activity运行时所在的进程名。
screenOrientation unspecified 默认值,由系统决定,不同手机可能不一致
landscape 强制横屏显示
portrait 强制竖屏显
behind 与前一个activity方向相同
sensor 根据物理传感器方向转动,用户90度、180度、270度旋转手机方向,activity都更着变化
sensorLandscape 横屏旋转,一般横屏游戏会这样设置
sensorPortrait 竖屏旋转
nosensor 旋转设备时候,界面不会跟着旋转。初始化界面方向由系统控制
user 用户当前设置的方向
theme "resource or theme " activity的样式主题, 如果没有设置,则activity的主题样式从属于应用程序, 参见元素的theme属性
  1. Intent的FLAG

Intent中定义了很多个FLAG,其中有几个FLAG也可以设定Activity的启动方式,如果Launch Mode设定和FLAG设定的Activity的启动方式有冲突,则以FLAG设定的为准。

FLAG 说明
FLAG_ACTIVITY_SINGLE_TOP 和Launch Mode中的singleTop效果是一样的。
FLAG_ACTIVITY_NEW_TASK 寻找和Activity关联(taskAffinity相同)的task,启动Activity;如果没有则新建task,启动Activity
FLAG_ACTIVITY_CLEAR_TOP LaunchMode中没有与此对应的模式,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity(包括它自己)出栈,然后启动新的Activity。与FLAG_ACTIVITY_NEW_TASK合用,可打到类似singleTask的效果,但是不会复用Activity。
FLAG_ACTIVITY_NO_HISTORY Activity一旦退出,就不会存在于栈中。同样的,也可以在AndroidManifest.xml中设置“android:noHistory”。
FLAG_ACTIVITY_MULTIPLE_TASK 需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,系统会启动一个新的栈来容纳新启动的Activity。等同于singleInstance。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS Activity不会被放入到“最近启动的Activity”列表中。只有栈的根Activity设置这个FLAG才生效。
FLAG_ACTIVITY_CLEAR_TASK 需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,用于清除与启动的Activity相关栈的所有Activity。

Activity启动方式

  1. 显示启动
从Activity启动
Intent intent = new Intent(this, ActivityB.class);
startActivity(intent);
从Context启动
Intent intent = new Intent(this, ActivityC.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
  1. 隐式启动
        <activity
            android:name=".ActivityC">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <data android:scheme="app"/>
                <data android:host="detail_view"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        从Activity启动
        Intent intent = new Intent();
        intent.setData(Uri.parse("app://detail_view"));
        startActivity(intent);
        从Context启动
        Intent intent = new Intent();
        intent.setData(Uri.parse("app://detail_view"));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplicationContext().startActivity(intent);
        <activity
            android:name=".ActivityB">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="com.activity.B"/>
            </intent-filter>
        </activity>
        从Activity启动
        Intent intent = new Intent();
        intent.setAction("com.activity.B");
        startActivity(intent);
        从Context启动
        Intent intent = new Intent();
        intent.setAction("com.activity.B");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplicationContext().startActivity(intent);

你可能感兴趣的:(Activity那些事(一))