Android_四大组件之一Activity

来源:互联网 发布:程序员入职自我介绍 编辑:程序博客网 时间:2024/05/23 01:24

Activity作为用户交互的界面,其重要性不言而喻,其贵为四大组件之首,我们就分别从以下几个方面来聊一聊Activity。

1.正常的生命周期

2.异常的生命周期

3.启动模式

4.标志Flags

一、正常的生命周期:

正常情况下,活动的生命是下面这样的:

onCreate()

活动生命周期的开端,我们一般在此阶段进行初始化操作,比如设置布局、窗口等;该方法只在Activity创建时调用。

onRestart()

活动由后台转为前台时由该方法开始,比如界面A开启,跳转到活界面B,在从界面B返回界面A,这时界面A的生命周期以onRestart()方法开始。这里就可以看出,如果某一个Activity没有被销毁,那么,当这个界面从后台线程跳到可见线程时,不会走onCreate()方法。

onStart()

此时活动已经可见了,但还无法与用户交互,即我们在打开一个界面时,会发现一片空白,当然,这只是一小会儿的时间,这个时候用户是可以看当这个界面的,但却无法对该界面做什么操作。

onResume()

此时活动由后台转到了前台,已经可以与用户进行交互了。

onPause()

正在停止,程序还在前台,所以该方法不适合做耗时操作,因为这样会让用户感觉到下顿;

onStop()

活动即将停止,可以稍微做一些重量级的工作,但同样不能太耗时。

onDestroy()

活动即将被销毁,这是界面的终点,我们可以在该方法中释放掉资源。

问题一:onStart(),onResume(),onPause(),inStop的异同:

这两对似乎是做了同样的操作,实际上,它们只是评判标准不同,onStart()和onPause()是否可见来创建的回调,而onResume()和onStop()是以活动是否运行在前台来创建的回调,在实际开发用,其实并没有太大的区别;

问题二:活动A--->活动B经历了什么:

A.onPause-->B.onCreate()-->B.onStart()-->B.onResume()-->A.onStop();

二、异常的生命周期之系统配置所引起:

我们考虑这种情况,活动A需要从本地取出一张照片,对应分辨率下有对应的选择,当屏幕竖屏时,我们取到了一张图片,并且显示出来,这时屏幕旋转了会发生什么呢?

实际上,当系统检测出我们的一些系统配置发生变化时,这个活动将会被销毁且重新创建,不过在销毁之前,活动会提供onSaveInstanceState()函数来让我们保存数据等,当活动重新创建时(恢复)会调用onRestoreInstanceState()函数来让我们恢复数据。由此可能产生两个问题, 1,系统在什么时机才会调用这两个函数,2,我们应该保存哪些数据?

问题一、onSaveInstanceState()、onRestoreInstanceState()何时调用:

onSaveInstanceState()在系统配置改变时就会被用,比如屏幕的旋转、键盘的弹出等,此时我们可以得用Bundle将我们希望保存的数据存起来,数据保存没问题了,我们在再来看看如何取出数据。

那我们怎么知道我的活动该不该调用onRestoreInstanceState()呢,实际上,我们的系统很智能,它会判定这个即将要被销毁的活动有没有可能会被重新显示,如果可能的话则调用该函数。比如我们旋转屏幕时,销毁了当前的活动,但是当旋转完成后我们肯定还要显示这个活动,这时系统就会去调用onRestoreInstanceState()函数。在比如,我们按back退出该活动,仅仅就是退出而已。

问题二、该保存哪些数据呢:

活动在配置资源改变导致活动重建时,虽说实例被重建了,但并不代表之前的一切都烟消云散了,事实上,我们的系统会通过委托的机制(层层委托保存)将View上的一些数据保存下来,重建后自动恢复,我们需要保存的就是我们定义的成员变量。

这个活动重建来重建去,是不是太耗内存了?我们如何避免一些不必要的重建呢?Android提供了configChanges属性来帮助我们实现这个愿望。有个这样简单的例子,当键盘弹出收起时该活动就不会再被重建,所以不会再有onSavveInstanceState()和onRestrorInstanceState(),但会调用一个onConfigurationChanged()方法。

使用方法如下:

<activity

android:configChanges="keyboardHidden" //屏幕旋转

android:configChanges="orientation | screenSize"//键盘

/.>

三、启动模式:

launchMode这个概念应该不用再赘述。在讨论活动的launchMode之前我们先大致了解一下活动栈的概念。活动的任务栈由TaskAffinity(任务相关性)来决定,在默认情下,APP中的活动在任务栈的名称就是应用的包名。我们可以这样现解,一般情况下,一个APP只有一个任务栈来管理 活动。下面来说说四种启动模式吧。

1、standard 标准模式

标准模式即默认模式,这种模式就是标准的铁头娃,我们每启动一个活动时,我啥也不管,只管创建一个新的实例放入到栈顶。

2、singleTop 栈顶单一模式

有人也称为栈顶复用模式,不过本人认为栈顶单一模式更加贴切,当我要启动一个活动A时,会去查看当前任务栈的栈顶是不是A,如果是A,那么不会创建A的实例,也不会重走什么生命周期,这时会调用onNewIntent()函数,否则会重新创建一个A。

3、singleTask 栈内单一模式

同样可称为栈内复用模式。我们需要两个判定条件,一个活动A需要的任务栈是否存 在,二任务栈中的A是否存在,我们启动一个A,首先会寻找 其想要的任务栈是否存在:

3.1 任务栈不存在,则创建它的任务栈并把A放入到新创建的栈中。

3.2 任务栈存在,任务栈中没有A的实例,创建A放入到该栈中。

3.3 任务栈存在,任务栈中有A的实例,将A之上的所有活动弹出置A于该栈顶,调用onNewIntent()方法。

一般在同一APPgh,我们不需要考虑栈是否存在的问题。

4、singleInstance 单实例模式

singleTask的加强模式,因为被设置为该模式的活A,它必须单独处于一个任务栈中,在栈中存在A的实例则复用,在存在A时,创建一个新栈且创建A的实例放入到新创建的栈中。

5、一个特别的情况

当应用A启动了应用B的活动C时,如果此时活动C的allowTaskReparenting属性为true的活。刚启动C时,应用B并没有被 启动,所以活动C在应用A的任务栈内。当应用B被启动时,系统检测出活动C是应用 B下的,这时会将活动C从应用A的任务栈转入到应用B的任务栈中。

6、如何定义启动模式

<activity android:launchMode="singleTop" />

四、Flags

Activity的Flags的作用主要有两个:设置启动模式、活动运行状态,一个Intent可以设置一个flag,也可以选择若干个进行组合。

1、FLAG_ACTIVITY_SINGLE_TOP

它和清单文件中设置singleTop作用一致。

2、FLAG_ACTIVITY_NEW_TASK

默认清况下,我们startActivity()启动一个新活动A时,活动A会和调用者在同一栈中,但是如果我们将A设置了FALG_ACTIVITY_NEW_TASK,如果是第一次执行,那第系统将会创建一个不丗于调用者的栈,并且创建A的实例放入到栈中,如果不是每一次执行,则不会再创建实例和栈。

3、FLAG_ACTIVITY_CLEAR_TOP

我们如果设置了该模式,如果栈内存在该实例A则不会创建新的实例,会将其上所有Activity出栈。如果在清单文件中活动A的launchMode是默认的,并且活动A又没有设置FLAG_ACTIVITY_SINGLE_TOP,此时活动A被 销毁重新创建。

如果在清单文件中活动A的launchMode是默认的,并且活动A又设置FLAG_ACTIVITY_SINGLE_TOP,此时系统会将Intent发给这人已存在的活,然后调用onNewIntent()函数。

















原创粉丝点击