Android四大组件之——Activity

Android四大组件之——Activityjava

Activity概述

移动应用体验与桌面体验的不一样之处在于,用户与应用的互动并不老是在同一位置开始,而是常常以不肯定的方式开始。例如,若是您从主屏幕打开电子邮件应用,可能会看到电子邮件列表,若是您经过社交媒体应用启动电子邮件应用,则可能会直接进入电子邮件应用的邮件撰写界面。android

Activity 类的目的就是促进这种范式的实现。当一个应用调用另外一个应用时,调用方应用会调用另外一个应用中的 Activity,而不是整个应用。经过这种方式,Activity 充当了应用与用户互动的入口点。bash

Activity 提供窗口供应用在其中绘制界面。此窗口一般会填满屏幕,但也可能比屏幕小,并浮动在其余窗口上面。一般,一个 Activity 实现应用中的一个屏幕。ide

Activity的生命周期和状态变动

当用户浏览、退出和返回应用时,应用中的 Activity 实例会在其生命周期的不一样状态间转换。Activity 类会提供许多回调,这些回调会让 Activity 知晓某个状态已经更改:系统正在建立、中止或恢复某个 Activity,或者正在销毁该 Activity 所在的进程。性能

生命周期的典型变动途径

附上官方的Activity生命周期图示。ui

须要注意一个点,是前一个Activity的onPause执行完,才会执行下一个Activity的建立,因此在onPause中不能执行较重操做。this

因为关于生命周期是一个老生常谈的问题了,其余生命周期在此就再也不作拆分解释了。google

保存和恢复界面状态

当发生配置变动(屏幕旋转或切换到多窗口)和因为内存不足系统对后台进程进行回收时,会致使Activity被销毁。此种状况发生时,系统会回调被销毁Activity的onSaveInstanceState(),经过Bunlde存储状态信息,以保存销毁瞬间当前Activity的状态。spa

当这些被销毁的Activity获得重建时,系统会将以前保存着状态信息的Bundle,经过方法onCreate或则onRestoreInstanceState传递给重建的Activity,以使其可以完成状态的恢复。code

在使用onCreate方法获取Bundle数据时须要进行null判断,而onRestoreInstanceState则不须要,且后者调用时机在onStart生命周期以后。

启动模式

任务和回退栈

任务是用户在执行某项工做时与之互动的一系列 Activity 的集合。这些 Activity 按照每一个 Activity 打开的顺序排列在一个返回堆栈中。返回堆栈按照“后进先出”的对象结构运做。

也就是说,任务是总体的概念——“外”,回退栈指代内部Activity的堆叠——“内”。

关于任务和回退栈,Activity能够这样要求

  • 进入任务前 在清单文件的activity标签中,能够经过taskAffinity来标识本身要进入的任务是哪一个(亲和性)。
  • 进入任务中 当Activity被开启,而后在存放于回退栈的过程当中,Activity能够经过清单文件中设置的启动模式launchMode,来设置回退栈对它的入栈安排。是直接进入(standard)、栈顶复用(singleTop)、栈内单例(singleTask),仍是独享一个任务(singleInstance)。

除了清单文件,固然还能够经过Intent设置参数,来标识Activity与任务的关联方式:

FLAG_ACTIVITY_NEW_TASK == singleTask

FLAG_ACTIVITY_SINGLE_TOP == singleTop

FLAG_ACTIVITY_CLEAR_TOP,若是要启动的 Activity 已经在当前任务中运行,则不会启动该 Activity 的新实例,而是会销毁位于它之上的全部其余 Activity,并经过 onNewIntent() 将此 intent 传送给它的已恢复实例(如今位于堆栈顶部)。FLAG_ACTIVITY_CLEAR_TOP 最常与 FLAG_ACTIVITY_NEW_TASK 结合使用。将这两个标记结合使用,能够查找其余任务中的现有 Activity,并将其置于可以响应 intent 的位置。

关于Activity的亲和性

咱们知道,经过在清单文件中配置Activity的taskAffinity,能够修改其亲和性(Activity 倾向于属于哪一个任务)。

taskAffinity 属性采用字符串值,该值必须不一样于 <manifest> 元素中声明的默认软件包名称,由于系统使用该名称来标识应用的默认任务亲和性。

亲和性可在两种状况下发挥做用:

  • 当启动 Activity 的 intent 包含 FLAG_ACTIVITY_NEW_TASK 标记时: 默认状况下,新 Activity 会启动到调用 startActivity() 的 Activity 的任务中。它会被推送到调用方 Activity 所在的返回堆栈中。可是,若是传递给 startActivity() 的 intent 包含 FLAG_ACTIVITY_NEW_TASK 标记,则系统会寻找其余任务来容纳新 Activity。一般会是一个新任务,但也可能不是。若是已存在与新 Activity 具备相同亲和性的现有任务,则会将 Activity 启动到该任务中。若是不存在,则会启动一个新任务。
  • 当 Activity 的 allowTaskReparenting 属性设为 "true" 时: 在这种状况下,一旦和 Activity 有亲和性的任务进入前台运行,Activity 就可从其启动的任务转移到该任务。

清除返回堆栈

默认状况下,若是用户离开任务较长时间,系统会清除任务中除根 Activity 之外的全部 Activity。当用户再次返回到该任务时,只有根 Activity 会恢复。 可是,可经过如下属性修改这一默认行为:

  • alwaysRetainTaskState 若是在任务的根 Activity 中将该属性设为 "true",则不会发生上述默认行为。即便通过很长一段时间后,任务仍会在其堆栈中保留全部 Activity。
  • clearTaskOnLaunch 若是在任务的根 Activity 中将该属性设为 "true",那么只要用户离开任务再返回,堆栈就会被清除到只剩根 Activity。也就是说,它与 alwaysRetainTaskState 正好相反。用户始终会返回到任务的初始状态,即使只是短暂离开任务也是如此。
  • finishOnTaskLaunch 该属性与 clearTaskOnLaunch 相似,但它只会做用于单个 Activity 而非整个任务。它还可致使任何 Activity 消失,包括根 Activity。若是将该属性设为 "true",则 Activity 仅在当前会话中归属于任务。若是用户离开任务再返回,则该任务将再也不存在。对于那些您不但愿用户可以返回到 Activity 的状况,可使用此属性进行设置。

Activity的启动

显示启动

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent) 
or 
startActivityForResult(intent,requestCode)
复制代码

若是是startActivityForResult开启:

  • onActivityResult接收结果
  • 被开启Activity关闭时在必要时候经过setResult(resultCode,intentData)传回结果

隐式启动

经过在<activity>标签下,配置<intent-filter>过滤器,来标识此Activity能够支持哪些意图。

<activity android:name="ShareActivity">
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="text/plain"/>
            <data android:mimeType="image/*"/>
        </intent-filter>
</activity>
复制代码

针对从后台启动Activity的限制

Android 10 (API 级别 29) 及更高版本对后台应用可启动 Activity 的时间施加限制。这些限制有助于最大限度地减小对用户形成的中断,而且可让用户更好地控制其屏幕上显示的内容。

几乎在全部状况下,后台应用都应显示有时效性的通知,以便向用户提供紧急信息,而非直接启动 Activity。

限制的例外状况

在 Android 10 或更高版本上运行的应用只有在知足如下一项或多项条件时,才能启动 Activity:

  • 应用具备可见窗口,例如前台 Activity。
  • 应用在前台任务的返回栈中拥有 Activity。
  • 应用在 Recents 屏幕上现有任务的返回栈中拥有 Activity。
  • 应用的某个 Activity 刚在不久前启动。
  • 应用最近为某个 Activity 调用了 finish()。这仅适用于在调用 finish() 时,应用在前台或前台任务的返回栈中拥有 Activity 的状况。
  • 应用具备受系统约束的服务。此状况仅适用于如下服务,这些服务可能须要启动界面:AccessibilityService、AutofillService、CallRedirectionService、HostApduService、InCallService、TileService、VoiceInteractionService 和 VrListenerService。
  • 应用中的某个服务受另外一个可见应用约束。请注意,绑定到服务的应用必须保持可见,以便后台应用成功启动 Activity。
  • 应用收到系统的 PendingIntent 通知。对于服务和广播接收器的挂起 Intent,应用可在该挂起 Intent 发送几秒钟后启动 Activity。
  • 应用收到另外一个可见应用发送的 PendingIntent。
  • 应用收到它应该在其中启动界面的系统广播。
  • 应用经过 CompanionDeviceManager API 与配套硬件设备相关联。此 API 支持应用启动 API,以响应用户在配对设备上执行的操做。
  • 应用是在设备全部者模式下运行的设备政策控制器。示例用例包括彻底托管的企业设备,以及数字标识牌和自助服务终端等专用设备。
  • 用户已向应用授予 SYSTEM_ALERT_WINDOW 权限(在 Android 10设备上运行的应用没法得到 SYSTEM_ALERT_WINDOW 权限。这是由于绘制叠加层窗口会使用过多的内存,这对低内存 Android 设备的性能十分有害。若是在搭载 Android 9 或更低版本的设备上运行的应用得到了 SYSTEM_ALERT_WINDOW 权限,则即便设备升级到 Android 10,也会保留此权限。不过,尚不具备此权限的应用在设备升级后便没法得到此权限了)。
相关文章
相关标签/搜索