好久没写博客了,最近找了份实习,各种事情乱七八杂,但是没写就是没写不能为自己找借口!
今天2017年2月20日,在这立个flag,接下来每星期至少写一篇博客!工作笔记,读书笔记,不想成为工程师的码农不是好的程序员!
正文:
生命周期
说到activity大家肯定都生命周期背的66的,那我们还是从生命周期讲开始,后面涉及一些要注意或则容易忽略的问题.
activity常见的生命周期:
- onCreate 表示Activity正在被创建
- onRestart 表示Activity正在被重启,一般用户行为使得activity从不可见状态变为可见状态onRestart就会被调用
- onStart 表示Activity正在被启动,Activity已经可见但是不是在前台
- onResume表示Activvity已经可见并且在前台和用户交互了
- onPause 表示Activity正在停止,Activity退出前台
- onStop 表示Activity即将停止 Activity处于不可见状态
- onDestory表示Activity即将被销毁
其实大家发现没有他们是一对一对的,onCreate 和onDestory是Activty的创建与销毁,onStart 和onStop是Activity的启动与停止,或则说是是否处于可见状态,onResume和onPause 则是是否位于前台(以前我不怎么理解,onStart的Activity已经可见但是不是在前台,其实这里的可见并不是用户可以看见,如果非要说是用户是否可见,想想dialog就知道什么是可见什么是前台了.)
这里有什么要注意的地方呢?
(1).有的页面的跳转或关闭前需要保存些数据,或则发送数据出去.很多人习惯在onPause里面做这些操作,打印过生命周期你会发现,只有在原来的onPause执行完成之后,新的Activity才会切换到onResume.所以不要在onPause里面做耗时操作,以免出现切换新页面卡顿的情况.
(2).以前有道面试题onCreate里面的参数Bundle saveInstanceState有什么作用,很多人都说恢复数据,但是没有实际的去运用却不知道什么时候数据保存下来了,什么时候恢复,怎么恢复,不同的恢复方法被调用的先后顺序有哪些注意的,首先什么时候保存?并不是只要Activity退出,在onSaveInstanceState()中out下就能保存下来.只有系统配置发生异常退出的时候onSaveInstanceState()才会被调用,其中恢复的数据可以在onCreate()或onRestoreInstanceState()中恢复,如果Activity异常退出并在onSaveInstanceState()中保存了数据,其中onRestoreInstanceState()的参数是必有值不为null的onCreate因为正常生命周期就会启动所以里面的参数需要判空操作,还有点需要注意的是的用onRestoreInstanceState来恢复数据,onRestoreInstanceState()是在onStart()之后调用就是也在onCreate()之后才能获得你要恢复的数据.(这里还有一点需要注意的是在清单文件中配置android:configChanges=”xxxx”可以捕获一些配置信息的改变,这样Activty的生命周期也会改变.)
(3).Activity的优先级
- 前台Activity,也就是正在和用户交互的Activity,优先级最高
- 可见但是不是前台进程的Activity
- 最次的是后台的Activity,在这个Activty的优先级是最低的,内存不够时很容易被回收,除此之外如果一个线程没有关联四大组件来提升自己的优先级也很容易被回收,所以需要耗时的操作,线程一般关联到Service,保证其有一定的优先级.
启动模式
大家这个也应该背的66的,下面我们来看下启动模式的一些细节
- standard:标准模式,哪个Activity启动了声明为standard或则没有声明启动模式的Activity,则新启动的这个Activity将会被压入到对应的任务栈中(注意前面的这句话!).其中应用的第一个Activity启动模式为standard时,这个Activity将被压入名字为包名的任务栈中.
- singleTop:栈顶复用模式 ,如果启动模式声明为singleTop的Activity位于栈顶,那么这个Activity将被复用,复用时它的onCreate()和onStart()将得不到调用,将会调用onNewIntent(),如果不位于栈顶那么还是会被重新创建.
- singleTask:栈内复用模式,其中这个模式最为复杂 ,栈内复用其实就是栈内单例模式,一个栈内最多只有一个实例,需要注意的是我们不光可以指定启动模式,也可以通过在清单文件配置android:Affinity=”“来指定Activity在哪个栈启动,如果被声明为singleTask已经存在他要启动的栈中,那么这个Activty也不会重新创建而是和singleTop一样调用onNewIntent(),它的onCreate和onStart将得不到调用(需要注意的是如果没有配置指定要启动的栈则默认为当前栈),他还有个特性是clearup,当他被复用时,位于他上面的Activty全部会被出栈.
- singleInstance:单实例模式,当被声明为singleInstance的Activity,会默认的创建一个新的栈来放置,并且它具有singleTask的所有特性包括栈内复用和clearup,需要注意的是声明为singleInstance的Activity启动后,别的进程隐式启动的将是这个Activity调用onNewIntent后的复用,直到这个任务栈被回收.
(什么时候是复杂的情况呢?比如说声明了启动模式指定了TaskAffinity,设置了allowTaskReparenting,不过应该没有人这么无聊.),还有个注意点是即使在清单文件中声明了启动模式,但是在代码里动态指定启动模式的优先级将会更高点.
小技巧:当我们隐式启动一个Activity时,我们无法获知这个Activity是否被声明或则是否存在,我们可以通过PakageManager的resolveActivity()或则是Intent的resolveActivity()返回值来判断,当其返回为空时,说明找不到这个Activity,避免程序抛出不必要的异常.