Table of Contents
一:Activity概述:
二:Activity的四种状态
1.运行状态
2.暂停状态
3.停止状态
4.销毁状态
三:Activity生命周期:
1.onCreate()
2.onStart()
3.onResume()
4.onPause()
5.onStop()
6.onDestory()
7.onRestart()
四:Activity的启动模式
使用Mainfest
"standard" (默认模式)
"singleTop"
"singleTask"
"singleInstance"
五:处理配置更改
1.在配置更改期间保留对象
2.自己处理配置更改
六:Intents and Intent Filters
1.开始一项活动
意图类型
2.启动服务
3.传送广播
Activity是Android的四大组件之一(活动,服务,内容提供器,广播),它是一种可以包含用户界面的组件(APP组件,提供可视化页面,View的载体,人机交互通道),主要用于和用户进行交互。Activity用于显示用户界面,用户通过Activity交互完成相关操作 , 一个App允许有多个Activity。【Activity
是一个Android应用程序的重要组成部分,与使用main()
方法启动应用程序的编程范例不同,Android系统Activity
通过调用与其生命周期的特定阶段相对应的特定回调方法(Java/Android中的函数调用&回调函数&自定义回调函数)来启动实例中的代码。】
OS——>Mainfest.XML—
当一个Activity位于返回栈(关于返回栈的概念下面再介绍)的栈顶时,这时Activity就处于运行状态,系统会将处于栈顶的Activity显示给用户。
当一个Activity不再处于栈顶位置,但仍然可见,这时Activity就进入了暂停状态。初学者可能会有这样的疑问,既然Activity都已经不在栈顶了,怎么会还可见呢,这是因为并不是每一个Activity都会占满整个屏幕的,比如对话框形式的Activity只会占用屏幕中间的部分区域。
当一个Activity不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。
当一个Activity从返回栈中移除后就变成了销毁状态。
当用户浏览,退出和返回应用时,应用中的 Activity
实例会在其生命周期中转换为不同的状态。Activity
类提供了一些回调允许活动知道一个状态已经改变的:该系统被创建,停止或恢复活性,或破坏该活动所在的过程。
必须实现此回调,该回调在系统首次创建活动时触发。在活动创建时,活动进入创建状态。在onCreate()
方法中,将执行基本应用程序启动逻辑,该逻辑应该在活动的整个生命周期中仅发生一次。(比如说加载布局,初始化布局控件,绑定按钮事件等)
这个方法在Activity由不可见变为可见时调用。(在 Activity 即将对用户可见之前调用。如果 Activity 转入前台,则接着调用 onResume()
,如果 Activity 转入隐藏状态,则接着调用onStop()
)
这个方法在Activity准备好和用户交互的时候调用。此时的Activity一定位于返回栈的栈顶,并且处于运行状态。(当活动进入Resumed状态时,它进入前台,然后系统调用onResume()
回调。这是应用程序与用户交互的状态。)
此方法又可以称为用户离开活动的第一个指示(尽管并不总是意味着活动正在被销毁); 它表示活动不再在前台(尽管如果用户处于多窗口模式,它仍然可见)
这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的activity,那么,onPause()方法会得到执行,而onStop()方法并不会执行。
这个方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。(onDestroy()
在活动被销毁之前调用。系统调用此回调因为:活动正在结束(由于用户完全解雇活动或因活动 finish()
被执行),或由于配置更改(例如设备旋转或多窗口模式),系统暂时销毁活动)
这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。
(当应用程序在多窗口环境中同时运行时 ,在Android 7.0(API级别24)及更高版本中受支持,系统会为每个窗口单独管理任务; 每个窗口可能有多个任务。)
当当前活动开始另一个活动时,新活动将被推到堆栈顶部并获得焦点。之前的活动仍在堆栈中,但已停止。当活动停止时,系统将保留其用户界面的当前状态。当用户按下“ 返回” 按钮时,当前活动将从堆栈顶部弹出(活动被销毁),之前的活动将恢复(其UI的先前状态将恢复)。堆栈中的活动永远不会重新排列,只能在当前活动启动时从堆栈中推送并弹出到堆栈中,并在用户使用Back退出时弹出按钮。因此,后堆栈作为“后进先出”对象结构操作。
在Mainfest中声明活动时,可以使用
元素的launchMode
属性指定活动应如何与任务关联。
该launchMode
属性指定有关如何将活动启动到任务的指令。launchMode
属性分配四种不同启动模式 :
"standard"
(默认模式)默认模式。系统在启动它的任务中创建活动的新实例,并将转到该实例。活动可以多次实例化,每个实例可以属于不同的任务,一个任务可以有多个实例。
"singleTop"
如果活动的实例已存在于当前任务的顶部,则系统通过调用其onNewIntent()
方法将转到该实例,而不是创建活动的新实例。活动可以多次实例化,每个实例可以属于不同的任务,一个任务可以有多个实例(但只有当后端堆栈顶部的活动不是活动的现有实例时)(如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。 )
singleTop模式分3种情况
"singleTask"
系统创建新任务并在新任务的根目录下实例化活动。但是,如果活动的实例已存在于单独的任务中,则系统会通过调用其onNewIntent()
方法将转到现有实例 ,而不是创建新实例。一次只能存在一个活动实例。(如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。 )
"singleInstance"
相同"singleTask"
,区别在于:系统不启动任何其他活动纳入此实例的任务。活动始终是其任务的唯一成员; 任何由此开始的活动都在一个单独的任务中打开。( 该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。 )
某些设备配置可能会在运行时更改(例如屏幕方向,键盘可用性以及用户启用 多窗口模式时)。发生此类更改时,Android会重新启动运行 Activity
( onDestroy()会
调用 )。重新启动行为旨在通过使用与新设备配置匹配的备用资源自动重新加载应用程序,帮助应用程序适应新配置。 onCreate()
要正确处理重新启动,活动必须恢复其先前的状态。
允许活动在配置更改时重新启动,将有状态对象带到活动的新实例。
如果重新启动活动需要恢复大量数据,重新建立网络连接或执行其他密集操作,则由于配置更改而导致的完全重新启动可能会降低用户体验。此外,可能无法使用Bundle
系统为回调保存的 活动状态完全恢复您的活动状态- 它不是为了承载大型对象而必须序列化然后反序列化在主线程上,它可能消耗大量内存并使配置变化缓慢。在这种情况下,可以通过使用此减轻重新初始化部分活动的负担 onSaveInstanceState()
ViewModel
。
由于处理配置更改的隐藏复杂性,建议不要自行处理配置更改。但是,如果无法使用首选(onSaveInstanceState(),ViewModels和持久存储)保留UI状态,则可以防止系统在某些配置更改期间重新启动活动。当配置发生变化时,应用程序将收到回调,以便可以根据需要手动更新活动。
要声明活动处理配置更改,编辑
清单文件中的相应元素,以包含android:configChanges
具有表示要处理的配置的值的属性。android:configChanges
属性的文档中列出了可能的值。最常用是"orientation"
,"screenSize"
和"keyboardHidden"
。"orientation"
值可防止屏幕方向更改时重新启动。该"screenSize"
值还可以防止方向更改时重新启动,但从Android 3.2(API级别13)开始。如果要在应用程序中手动处理配置更改,则必须在属性中声明"orientation"
和 "screenSize"
值android:configChanges
。该"keyboardHidden"
键盘可用性更改时,值可防止重新启动。可以通过用管道|
符分隔属性来声明属性中的多个配置值。
intent是一个消息对象,可用于从另一个应用程序组件请求操作。尽管意图以多种方式促进组件之间的通信,但有三个基本用例:
活动表示应用程序中的单个屏幕。可以通过将意向传递给StartActivity()来启动活动的新实例。intent描述了启动和携带任何必要数据的活动。
如果要在活动结束时接收该活动的结果,请调用StartActivityForResult()。活动在活动的onActivityResult()回调中将结果作为单独的intent对象接收。
1.显式意图通过提供目标应用程序的包名称或完全限定的组件类名称来指定哪个应用程序将满足intent。通常会使用显式intent在自己的应用中启动组件,因为您知道要启动的活动或服务的类名。例如,您可以在应用中启动新活动以响应用户操作,或启动服务以在后台下载文件。
是应用程序清单文件中的表达式,用于指定组件要接收的意图类型。例如,通过为活动声明一个意图过滤器,您可以让其他应用程序以某种意图直接启动您的活动。同样,如果您没有为活动声明任何意图过滤器,则只能使用明确的意图启动它。)建立intent:Building an intent
2.隐式意图不命名特定组件,而是声明要执行的常规操作,这允许来自另一个应用程序的组件处理它。例如,如果要向用户显示地图上的位置,则可以使用隐式意图请求另一个有能力的应用程序在地图上显示指定位置。(当使用隐式intent时,Android系统会通过将intent的内容与设备上其他应用程序的manifest文件中声明的intent过滤器(
)进行比较来找到适当的组件。如果intent与intent过滤器匹配,则系统启动该组件并将其传递给对象。如果多个intent过滤器兼容,系统将显示一个对话框,以便用户可以选择要使用的应用程序。【应用程序组件应为其可以执行的每个唯一作业声明单独的过滤器。例如,图片库应用中的一个活动可能有两个过滤器:一个用于查看图像的过滤器,另一个用于编辑图像的过滤器。当活动开始时,它会检查Intent
并根据中的信息Intent
(例如显示编辑器控件)来决定如何操作】
每个intent过滤器都由
应用程序清单文件中的元素定义,嵌套在相应的应用程序组件(例如
元素)中。在其中
,您可以使用以下三个元素中的一个或多个来指定要接受的意图类型:
在name
属性中声明接受的intent动作。值必须是操作的文字字符串值,而不是类常量。
声明数据的接受,使用该指定数据的URI(各个方面的一个或多个属性的类型
scheme
,host
,port
, path
)和MIME类型。
在name
属性中声明接受的intent类别。值必须是操作的文字字符串值,而不是类常量。
例如:
3.pendingIntent
pendingIntent是一种特殊的Intent。主要的区别在于Intent的执行立刻的,而pendingIntent的执行不是立刻的。pendingIntent执行的操作实质上是参数传进来的Intent的操作,但是使用pendingIntent的目的在于它所包含的Intent的操作的执行是需要满足某些条件的。
主要的使用的地方和例子:通知Notificatio的发送,短消息SmsManager的发送和警报器AlarmManager的执行等等。
pendingIntent对象,使用方法类的静态方法 :
getActivity(Context, int, Intent, int)------->跳转到一个activity组件、
getBroadcast(Context, int, Intent, int)------>打开一个广播组件
getService(Context, int, Intent, int)-------->打开一个服务组件。
服务是一个在后台执行操作而不使用用户界面的组件。使用Android 5.0(API级别21)及更高版本,您可以使用JobScheduler启动服务。
对于早于Android 5.0(API级别21)的版本,可以使用服务类的方法启动服务。您可以通过将意向传递给StartService()来启动服务以执行一次性操作(例如下载文件)。意图描述了启动服务并携带任何必要的数据。
广播是任何应用程序都可以接收的消息。系统为系统事件提供各种广播,例如系统启动或设备开始充电时。通过将intent传递给sendBroadcast()或sendOrderedBroadcast(),可以将广播传递给其他应用程序。