Activity 简介
绝大部分Activity是用于和用户交互的,Activity会创建一个交互窗口,可以通过调用setContentView(View)来放置一个布局在activity的窗口中。
通常是在PhoneWindow的DecorView中,显示UI会延迟大概300ms左右,在此之前,View还没有被填充,所以要在onCreate()中获去View的尺寸,需要创建一个线程,在线程中等待300ms以上,再获取View的尺寸。Activity提供的窗口可以是充满屏幕的,也可以是悬浮窗口(通过windowIsFloating来设置),或者嵌入到其它的Activity中,通过ActivityGroup来实现。
Activity生命周期图
当一个activity被启动时,他就会处于Activity Task的顶端。
大部分实现Activity的子类需要重写onCreate(Bundle)和onPause(),在onPause()方法中通常使用ContentProvider来保存用户信息的改变,或者使用SharedPreference来保存用户设置的改变。在这个方法中通常也清除Activity产生的资源,避免造成浪费。
当一个activity失去焦点,但是任然可见时,它就会进入暂停状态onPause(),此时它会保留所有的状态和成员信息;但此时的activity将可能会被系统关闭。
activity通常会频繁的调用onPause()和onResume()方法,所以这两个方法中执行的代码应该是较为轻量的。但任然应该把保存数据的代码写在onPause()方法当中。当调用onPause()时,会调用onSaveInstaneState(Bundle)和onRestoreInstanceState()来暂存view的状态,并且将在调用onCreate(Bundle)时接收,但这个方法并不属于activity生命周期的一部分,所以有些时候它并不会被调用,如果复写这两个方法将能扩展它的功能,并且使activity更加健壮,以应对一些不可预见的错误。
对于需要重复加载的事务,应该写在onResume()中。onCreate()中就放一些初始化的操作,即这些操作只需要执行一次。
通过设置view的android:saveEnable属性或者调用setSaveEnable()可以决定view的状态state是否被保存。
当一个activity失去焦点,并且不可见时,它就会进入停止状态onStop(),此时它任然能保留状态和成员信息;但此时的activity更容易被系统关闭。调用onRestart()方法可以重新启动activity。
对于启动了另一个activity的情况,只有当被启动的activity执行到onResume()时,才能知道它是否会使当前的activity变得不可见,此时才能决定当前的activity是否调用onStop()。
activity的生命周期
1.1总的来说activity的生命周期就是六个状态,7个方法。如图:
1.2上述activity的六个状态以及相关情况如下:
activity状态 | 执行完之后方法之后所处的状态 | 对用户是否可见 | 是否可以与用户交互 | activity在该状态下停留时间长短 |
Created | OnCreate()方法执行完毕之后 | 不可见 | 不可交互 | 短暂 |
Started | OnStart()方法执行完毕之后 | 可见 | 不可交互 | 短暂 |
Resumed(running) | OnResume()方法执行完毕之后 | 可见 | 可交互 | 较长 |
Paused | OnPause ( ) 方法执行完毕之后 | 可见 | 不可交互 | 较长 |
Stoped | OnStop ( ) 方法执行完毕之后 | 不可见 | 不可交互 | 较长 |
Destroyed | OnDestroy ( ) 方法执行完毕之后 | 不可见 | 不可交互 | 短暂 |
注意:其中Paused这个状态有两种情况:
第一种:有一个半透明的activity完全覆盖在本activity上边。
第二种:有一个activity覆盖在本activity上边,但是没有完全覆盖。
1.3各种情况下生命周期走的方法:
情况1:从acitivityA跳到activityB,首先activityA执行的是oncreate()--onstart()--onresume(),当从activityA跳转到activityB的时候,此时执行的方法activityA的onPause()--activityB的oncreate()----activity B的onstart()---activityB 的onresume()--activity A的onstop()方法,然后点击返回键,从activityB返回到activityA,此时执行的方法是activityB的onpause()--activityA的onrestsrt()--activityA的onstart()--activityA的onresume()--activityB的onstop()---activityB的ondestroy()方法。
情况2:当这个activity启动之后,退居后台,已经执行了onstop方法,但是此时系统内存不够的时候,杀死了该process,那么下次要执行的就是oncreate--onstart()--onresume(),而不是执行onrestart()--onstart()--onresume()方法。
activity的启动模式
2.0 Application, Task ,Process之间的区别
Application,在android中,总体来说就是一组组件的集合,众所周知,android是在因公层组件化程度非常高的系统,android开发其实就是写android四大组件中的我们需要的组件,并且在清淡文件中注册这些组件之后,把这些组件和组件使用到的资源打包称apk,然后这就是一个Application,其实Application和组件的关系可以在manifest文件中清晰体现出来,在apk安装的时候,系统会读取application中清淡文件manifest的信息,将所有的额组件解析出来,一边在运行时进行实例化。
Task是在程序运行的时候,只针对activity的概念,即Task是一组相互关联的正在运行的activity的集合。它是存在与framework层的一个概念,控制界面的跳转和返回,framework是以栈的数据结构方式管理用户开启的activty,也可以说activity是存在于back stack(回退栈)中的。而且task是可以跨应用的,即不同的app的activity是可以在同一个Task中的,主要是为了保证用户操作的连贯性。(比如在app中的activityA页面打开一个网页(使用第三方浏览器),当用户浏览完网页的信息之后,按back键,就会回到activityA页面。)
Process即进程是操作系统进行资源分配和调度的一个独立单位,默认情况夏,一个应用程序的所有组件会在同一个进程中,但是应用的不同组件也是可以运行在不同的进程中的,只需要在清单文件中进行注册的时候,声明process属性:
<activity android:name=".health.healthListActivity"
android:process="processb">
</activity>
2.1acitivty的四种启动模式
<1>standard--默认的启动模式,同一个任务中可以存在多个该activity的实例。不断的利用startActivity()或者 startActivityForResult()启动该activty,都会重新创建该activity的新实例。
<2>singleTop--(作用:防止activity被重复启动多个)--同一任务栈中可以存在多个该activity的实例,但是当该actiivty已经处在任务栈的栈顶时,此时再利用startActivity()或者startActivityForResult()启动该activity,则会复用栈中已经存在的该activity实例;如果该activity任务栈的栈顶时,此时就会重新创建新的该activity实例。
<3>singleTask--(作用:保证任务栈中只有一个该activity实例)--同一任务栈中只能存在一个该activity的实例,当该activity不在任务栈的栈顶的时候,此时利用startActivity()或者startActivityForResult()启动该activity,则直接杀死该activity上边的所有activity实例,让该activiyt处在任务栈的顶端;如果该activity在任务栈的顶端的时候,此时再利用startActivity()或者startActivityForResult()启动该actiivty,则直接走onNewIntent()--onRestart()--onStart()--onResume()方法。
<4>singInstance--(作用:保证整个系统内存中都只有一个该activity实例)--在一个新的任务栈中创建该activity的实例,并且让多个应用共享栈中的该activiyt实例,一旦存在,如果再次 利用startActivity()或者startActivityForResult()启动该actiivty,均是复用已经存在的该activity实例。