Activities简介
Activity类是android应用程序中的一个重要组件,activity对象组织和启动的方式更是android平台应用程序模型的基础。与范式编程使用main()函数启动应用不同,android系统在Activity实列中通过调用符合当前Activity生命周期的回调方法来执行代码。
本文档介绍activities的基本概念,并提供一些使用activities的轻量级指导。如需构建App最佳实践的更多信息,请参考 Guide to App Architecture。
activities的概念
移动应用程序体验与桌面应用程序不同,用户与应用程序的交互不总是在同一个地方开始。程序的开启经常是不确定的。比如,你在主屏幕开启一个Email app你可能看到的是email列表,但如果你在使用社交媒体app的途中打开一个email app,你可能会直接前往email的编辑页面。
Activity类就是为解决以上问题而设计的。一个app调用另一个app时,实际上调用的是该app的activity而不是调用的整个app。activity通过这种方式作为app和用户交互的入口点。可以通过继承Activity类来实现一个activity。
Activity提供了app绘制其UI的窗口。该窗口通常会填充整个屏幕,但可能比屏幕小,并且浮动在其他窗口之上。通常,一个activity实现着一个屏幕。例如,一个app的活动实现了选项屏幕,另一个activity实现了图片选择屏幕。
大多数应用包含多个屏幕,这意味着它们有多个activity。通常,一个应用程序会有一个 main activity,当用户启动app时,该acitvity所实现的屏幕就会首先出现在用户面前。然后,每个activity就可以开启其他activity以执行不同的操作。例如,一个简单的邮件app的 main activity 可能会提供一个展示收件箱的屏幕。从收件箱屏幕开始,main activity可以启动其他提供了例如邮件编辑和打开个人邮件屏幕的activity.
虽然app中的activity通过相互协作以形成有粘性的用户体验,但是每个activity仅仅是松散地绑定到其他activity,app中的活动通常有最小的依赖关系。实际上,activity经常会启动其他应用的activity。例如,一个浏览器app可能会启动一个社交媒体app的分享activity。
要在app中使用activity,就必须在app的manifest文件中注册activity的信息,并且正确地管理activity的生命周期。本文档的其他部分将介绍这些内容。
配置manifest文件
要想在app中使用activity,必须先定义activity,并在manifest文件中表明activity的属性。
定义activity
打开manifest文件,添加一个<activity>元素作为<application>元素的子元素以定义activity。例如,
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
<activity>元素唯一需要的属性是android:name,该属性指向activity的类名。还可以添加定义activity特征的属性,例如标签、图标或UI主题。有关这些属性和其他属性的更多信息,请参见<activity>元素参考文档。
注意:在发布应用程序后,不应更改activity名称。如果这样做,可能会破坏某些功能,例如应用程序快捷方式。有关发布后避免更改的更多信息,请查看无法更改的内容。
定义intent filters
intent filters是android平台上的一个非常强大的特性。它们提供了启动activity的能力,不仅基于明确的请求,还能基于不明确的请求。例如,一个明确的请求会告诉系统"打开Gmail app中的发送邮件activity"。相比之下,一个不明确的请求会告诉系统"打开任何一个能发送邮件的activity"。当系统UI询问用户在执行任务时使用哪个应用程序时,这就intent filters在起作用。
可以通过在<activity>元素中定义<intent-filter>属性来使用该特性。<intent-filter>元素的定义包含一个<action>元素和可选的<category>元素和<data>元素。这些元素结合在一起,可以指定您的activity可以响应的intent类型。例如,下面的代码片段演示如何配置发送文本数据的activity,并接收来自其他activity的请求:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
在本例中<action>元素指定本activity发送数据。将<category>元素设为default使activity能接收启动请求。<data>元素指定了该activity能发送的数据类型。以下代码片段展示了如何调用上述activity:
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, textMessage)
}
startActivity(sendIntent)
如果你想要自己的app“自给自足”并且不允许其他app触发你的app的activity,你不需要使用其他任何intent filters。不想要其他程序获取到的activity不应该有intent filters,您可以自己通过显式intent(在app范围内)来启动这些activity。有关activity如何响应intent的更多信息,请查看ntents and Intent Filters.
定义Permissions
您可以通过manifest文件的<activity>标签那些app可以启动指定的activity。一个父activity不能启动一个子activity除非这两活动在manifest文件定义了相同的权限。如果您为一个activity定义了<uses-permission>元素,调用的activity必须要有与之相应的<uses-permission>元素。
例如,如果你想使用一个假设名为SocialApp的app在社交媒体上分享邮件,SocialApp自己必须定义一个调用它的app也必须有的permission:
<manifest>
<activity android:name="...."
android:permission=”com.google.socialapp.permission.SHARE_POST”/>
为了可以调用SocialApp,你的app必须在适配SocialApp中的permission设置:
<manifest>
<uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>
有关权限和安全相关的更多信息,请查看Security and Permissions.
管理activity的生命周期
在activity的生命周期中,activity经历了许多状态。您可以通过一系列的回调方法来处理这些状态间的转换。接下来的部分,将会介绍这些回调方法。
onCreate()
该回调方法必须实现,该方法在系统创建activity时创建。该方法的实现必须初始化创建的activity的基本组件。例如,app中创建的views和绑定到列表的数据应该在此处完成。最重要的是,
必须在该方法内调用setContentView()方法以定义activity的用户界面的layout。
当onCreate()方法执行完毕后,下一个回调的方法是onStart()
onStart()
当onCreate()方法执行完毕后,activity进入started状态,并对用户变为可见。该回调方法包含使当前activity变为可与用户交互的前台activity最后的准备工作。
onResume()
系统仅在activity与用户开始交互前调用该方法,此时,activity处于activity栈的顶部,并获取所有的用户输入。一个app的大多数核心功能在onResume方法中实现。
onPause()方法总是在onResume方法之后调用。
onPause()
系统会在activity失去焦点和进入暂停状态时调用onPause()方法。例如,当用户点击"后退"或"最近"按钮时,就会出现这种状态。当系统为activity调用onPasuse()方法时,从技术上讲,该activity仍然部分可见,但通常表明用户正在离开activity,并且该activity会很快进入stopped状态或者resumed状态。
如果用户期待更新UI,处于暂停状态的activity可以继续更新UI。例如,一个包含地图导航或者媒体播放器的activity。即使这些activity失去了焦点,用户仍然希望UI继续更新。
不应该在onPause()方法中保存程序或者用户数据、调用网络、执行数据库事务。如需更多关于数据保存的信息,请查阅Saving and restoring activity state.
onStop()
系统会在activity不再对用户可见时调用onStop()方法。这可能是因为activity正在被销毁,一个新的activity正在开始,或者一个现有的activity正在进入恢复状态,并且正在覆盖已停止的activity。在所有这些情况下,停止的activity都不再可见。
如果activity正在返回与用户交互的状态,系统调用的下一个回调方法是onRestart(),如果活动被完全终止,则会调用onDestroy().
onRestart()
当处于停止状态的activity即将重新启动时,系统将调用此回调。onRestart()将activity恢复到该activity stopped时的状态。该方法后面总是跟着onStart()方法。
onDestroy()
系统在activity销毁前调用该方法。
这个回调是activity接收到的最后一个回调方法,onDesty()的实现通常是为了确保在activity或包含该activity的进程被销毁时释放所有资源。本节只对activity的生命周期进行简介。有关活动生命周期及其回调的更详细处理,请参见活动生命周期。