Activity那些事(一)

Activity生命周期

  1. Launcher 启动 Activity
  2. Activity A 启动 B

    如果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为透明

    <style name="TransparentTheme" parent="Theme.AppCompat.NoActionBar">
        <!--不设置activity进入和退出动画样式-->
        <item name="android:windowAnimationStyle">@null</item>
        <!--设置窗口的背景为透明,设置透明背景必须要设置此项-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--设置窗口的背景是否为半透明,设置透明背景必须要设置此项-->
        <item name="android:windowIsTranslucent">true</item>
        <!--设置状态栏的背景为半透明-->
        <item name="android:windowTranslucentStatus">true</item>
    </style>

启动模式与属性

  1. Activity栈简介

一个ActivityRecord对应一个Activity,一个Activity可能对应多个ActivityRecord,这与Activity的启动模式有关。

使用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的包名
launchModestandard默认启动模式;A启动B,每次启动都会在A的Task中新建一个B。
singleTopA启动B,B的启动模式为singleTop,启动流程如下所示。复用B时,B在onResume前执行noNewIntent。
singleTaskActivity A启动Activity B ,B的启动模式为singleTask,如果B的taskAffinity与A的不同,则寻找与B的taskAffinity相同的Task启动B;如果相同则在A的Task中启动B。流程图如下所示。如果B设置了新的taskAffinity,则这个栈会加到最近启动列表中。
singleInstanceA启动Activity B ,B的启动模式为singleInstance,新建一个与B的taskAffinity相同的Task启动B,而且这个Task中有且只有B这一个Activity。重复启动B则复用B,复用B时,B在onResume前执行noNewIntent。
clearTaskOnLaunchtrue/falseA启动B, 然后返回Home, 从新启动 B,如果A设置了这个属性为true,则不显示B,否则显示B
configChangesmcc国际移动用户识别码所属国家代号是改变了,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"
enabledtrue/falseactivity 是否可以被实例化
excludeFromRecentstrue/false是否可被显示在最近打开的activity列表里(true不显示,false显示,只有栈的根Activity设置该属性才生效)。
exportedtrue/false是否允许activity被其它程序调用
permission权限名称设置启动这个Activity所需要的权限。
process进程名称一个activity运行时所在的进程名。
screenOrientationunspecified默认值,由系统决定,不同手机可能不一致
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_TOPLaunchMode中没有与此对应的模式,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity(包括它自己)出栈,然后启动新的Activity。与FLAG_ACTIVITY_NEW_TASK合用,可打到类似singleTask的效果,但是不会复用Activity。
FLAG_ACTIVITY_NO_HISTORYActivity一旦退出,就不会存在于栈中。同样的,也可以在AndroidManifest.xml中设置“android:noHistory”。
FLAG_ACTIVITY_MULTIPLE_TASK需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,系统会启动一个新的栈来容纳新启动的Activity。等同于singleInstance。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTSActivity不会被放入到“最近启动的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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值