Android学习的第一步从四大组件开始
Activity是App用于人机交互的最常用的组件,往往用户操作都需要和Activity打交道(当然也有没有Activity的App)。
在开发过程中,可以对Activity的进行的操作一般在三个方面:
onCreate()
中使用。说一点点
在AS中新建Activity时,系统会自动在生成 AndroidManifest.xml 进行注册,生成Activity.java
和Layout.xml
文件并关联。
本文涉及Activity的注册、生命周期、异常情况下的生命周期以及启动模式。
Activity 使用前必须在清单文件中注册,这样系统才能知道这里有一个Activity可以使用,才能访问它。
要注册 Activity需要打开 AndroidManifest.xml 文件进行注册,并将 元素添加为 元素的子项,至于 AndroidManifest.xml 文件是什么?怎么注册?来,我们看个饭粒:
按照常规xml文件的类型来理解一下:根节点manifest
就是我们当前的注册文件,其中有两个属性,一个声明了命名空间,另一个指定了包名。注册文件中有一个Application元素,Application保存5条相关属性,并且持有2个Activity元素。每个Activity有1个相关属性(这里有一个 后面会提到)。
这样看来 AndroidManifest.xml 文件,就是整个App的“结构树”和“配置说明”。
补充一点点:
AndroidManifest.xml 是每个android程序中必须的文件。它位于整个项目的根目录,描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。 除了能声明程序中的Activities, ContentProviders, Services, 和Intent Receivers,还能指定permissions和instrumentation(安全控制和测试)
引用自:Android的AndroidManifest.xml文件的详解
这样一想,注册Activity也就简单多了,就是在
节点下添加一个
节点,并且保证
节点的android:name
属性与相应的*.java
文件保持一致。
但是,这样还不是结束,注意一下上面提到的节点
当我在一个
节点下添加了多个
节点时,这时在程序看来每一个
在优先级上是没有区别的,那么在启动时应该启动哪个Activity?为了防止程序出现疑惑的情况,我们需要指定第一个被启动的Activity。
android.intent.action.MAIN
的Activity会优先被程序启动。android.intent.category.LAUNCHER
决定了当前Activity会不会出现在程序列表中,生成一个程序入口。在注册MainActivity时需要使用
进行声明,并且Main和LAUNCHER同时设定才有意义
补充一点点
当Application中设置多个包含Main和LAUNCHER的,程序列表会出现多个图标分别对应不同的Activity入口,点击任何一个图标,则启动对应的Activity。
引用自:为多个Activity配置android.intent.category.LAUNCHER和android.intent.action.MAIN
生命周期就是指一个对象的生老病死(从摇篮到坟墓的整个过程)。 ——百度百科
一直想找一个解释:Activity生命周期是什么?查了一下无非是“四大状态七大方法“,看着感觉解释很僵硬。就和下面的问答一样:
问:电脑是什么?
答:主机+显示器+…+键盘+鼠标。
嗯…说的很正确,但是好像感觉哪里不对劲?
PS:现在还是没有找到一个合适的解释,这里只是希望不要将“四(五)大状态七大方法“过度的分开理解,也不要按照的“生命周期图”的顺序死记硬背。
(1)onCreate():在Activity创建时调用,通常做一些初始化设置。
(2)onStart():在Activity准备显示在屏幕前调用,调用后Activity处于可见状态。
(3)onResume():在Activity获取焦点开始与用户交互时调用。
(4)onPause():表示Activity暂停,一般情况下onStop()会马上被调用。但是在当前Activity被其他Activity部分覆盖或锁屏时调用时仅调用onPause()。
(5)onStop():在Activity进入后台对用户处于不可见状态时调用。
(6)onDestroy():在Activity即将被销毁时调用。
(7)onRestart():在Activity从停止状态再次启动时调用,一般为用户行为导致。
由图可视,以上为Activity的五种状态(Staring很短暂,可能直接合并到Staring,所以有的文章中为四种状态)
1.Starting(启动状态):创建Activity,启动Activity进入Running
2. Running(运行状态):Activity位于任务栈顶部(当前可交互操作的Activity处于此状态)。
3. Paused(暂停状态):Activity处于可见状态,但是无法进行交互操作。
4. Stopped(停止状态):Activity完全不可见,但仍保留相关成员和数据。
5. Destroyed(销毁状态):Activity被销毁,等待被系统回收
状态转换过程(常规情况下)
当系统资源配置发生改变以及系统内存不足时,activity就可能被杀死。
onSaveInstance()
来保存当前activity状态,这个方法的调用时机是在onStop()之前,与onPause()无必然时序关系。onRestoreInstanceState()
来恢复原Activity,该方法在onStart()之后调用。补充一点点
1、系统本身会在异常恢复的过程中自动做一部分恢复工作,方法与Activity相同,每个view都实现了onSaveInstanceState()和onRestoreInstanceState()。
2、防止重新创建activity:activity指定configChange属性来不让系统重新创建activity。
例如:指定旋转屏幕时不重新创建:android : configChanges = "orientation"
PS:如果minSDKVersion & targetSDKVersion有任何一个大于13,则需要额外添加screenSize
。
activity有四种启动模式:standard、singleTop、singleTask、singleInstance
使用相应的启动模式时需要在manifest文件中声明:
如上代码所示,如果设置OtherActivity
的启动模式为singleTop
,需要在该Activity对应的标签中添加属性(注意:是属性不是子Node)android:launchMode="singleTop"
activity的默认启动模式。activity启动时默认重新实例化,进入启动它的activity所属的任务栈中,并且standard模式的activity可以被多次实例化。即在同一个任务中可以存在多个activity的实例。
补充一点点
在非Activity类型的context(如ApplicationContext)并没有所谓的任务栈,所以不能通过ApplicationContext去启动standard模式的Activity。
如果以singleTop模式启动Activity,如果当前Activity已经有实例位于任务栈的栈顶,Activity不会被重新创建,而是回调它的onNewIntent方法。如果以singleTop模式启动的Activity的一个实例已经存在与任务桟中,但是不在桟顶,那么它的行为和standard模式相同,也会创建多个实例。
如果以singleTask模式启动Activity。那么在当前任务栈中,被启动的Activity只能存在一个实例,多次启动此Activity不会被重新创建单例,系统会回调onNewIntent。比如Activity A ,系统首先会寻找是否存在 A 想要的任务栈,如果没有则创建一个新的任务栈,然后把Activity A 压入栈,如果存在任务栈,然后再看看有没有 Activity A 的实例,如果实例存在,那么就会把A调到栈顶并调用它的 onNewIntent() 方法,并清除它当前所在任务中位于它上面的所有的activity使其位于栈顶,如果不存在则把它压入栈。
补充一点点
这里提到了 被启动的 Activity A 想要的任务栈 这里涉及 Activity 的一个新的属性taskAffinity
,有兴趣的请点这里解开Android应用程序组件Activity的"singleTask"之谜