碰到一面试题 简述activity/service生命周期?android
组件的生命周期 面试
应用程序组件都有一个生命周期,从响应Intent的Android实例开始到这个实例被销毁。在这期间,他们或许有效或许无效,有效时或许对用户可见或许不可见。下面咱们就来讨论四个基本组件的生命周期,包括在生命周期内的各类状态,以及状态之间的转换。这几种状态可能的结果是:进程让他们中止, 而后实例被销毁。
1、activity生命周期
一个activity有三个基本的状态:
@ 当activity在前台运行时(在activity当前任务的堆栈顶),为活动或者运行状态。这时activity会响应用户的操做。
@ 当activity失去焦点可是对用户仍然可见时为paused暂停状态。此时,别的activity在他的上面,透明或者备有被所有覆盖。因此其中一些暂停的activity也能够被显示。一个暂停的activity是处于活动状态的(他维护着全部的状态保存着信息,而且依然附着在窗口管理器)。
@ 若是一个activity彻底被另外一个activity所掩盖那他会处于stop状态。但仍然保存着原来的状态和信息。然而,若是别的地方须要更多的内存并且这个activity仍一直处于隐藏状态,那么系统有可能会杀死他的进程。
若是一个activity是暂停或者中止状态,系统能够清理他们占用的内存,或者调用finish()方法,或者直接结束他的进程。当他再次显示给用户时,会彻底的从新运行而且加载之前所存储的信息。
activity状态之间的转换,是经过之前的受保护方法完成的:
void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()
这些都是钩子函数,你能够重写他们,当状态改变时作一些适当的处理。全部的activity在首次运行时必须实现onCreate()方法来初始化安装。activity能够实现onPause()来提交数据改变,而后准备中止与用户的交互。
调用超类
每个实现的activity生命周期方法都会先调用一下父类的方法,例如:
view plaincopy to clipboardprint?
protected void onPause() {
super.onPause();
. . .
}
protected void onPause() {
super.onPause();
. . .
}
经过这二者比较?,这7个方法定义了一个activity的整个生命周期的方法。你能够实现而且监测这三个嵌套循环:
@ 整个生命周期
调用onCreate()方法和onDestroy()之间称为一个activity的完整的生命周期。activity会在onCreate()里执行全部的初始化安装,在onDestroy()方法里释放全部的剩余资源。例如:一个从网络下载程序的线程,就须要在onCreate()方法里建立,在onDestroy()方法里销毁。
@ 可见生命周期
可见生命周期是从onStart()方法到onStop()方法的时间。这段时间,用户会在屏幕上看到这个activity。尽管他可能不是在最顶层显示,也没有和用户进行任何交互。这两个方法之间,你能够保持须要向用户显示的资源。例如:你能够在onStart()方法时注册一个BroadcastReceiver检测某些变化来改变你的界面,当用户看不到这个activity的界面时能够在onStop()里注销这个BroadcastReceiver。这两个方法能够被调用不少次,在可见和对用户隐藏时,做为候补的activity待命。
@ 前台显示周期
一个activity从onResume()方法指导一个onPause()方法称为前台显示周期。此时他在其余的activity之上显示而且与用户交互。一个activity能够频繁的在这两个方法之间过分,例如:当设备休眠或者另外一个新的activity启动时,它会进入onPause()状态,当一个activity运行结束或者新的接收到Intent请求时,activity的onResume()会被调用。所以,这两个方法里的代码量会不多。
下图说明了上面说的几个循环,里面的箭头说明了两个状态之间是否能够相互转换。有色的椭圆是activity主要的几个状态。正方形和长方形表明activity在状态之间转变时咱们能够实现的一些回调方法。
注意killable这列,它指明了进程在调用方法返回后是否能够被系统杀死,而不执行其余的代码。onPause(), onStop(), and onDestroy()这三个方法能够,由于onPause方法首先被执行,他是惟一一个必定会被调用的方法当进程被杀死时,可是onStop()和onDestroy()方法不会。所以,你能够在onPause()方法里保存一些连续的数据,例如编辑。
killable这列被标记成no的方法,保护activity防止他们被调用时,被进程杀死。例如:一个activity是处于可被杀死的状态,当activity从onPause()方法跳转到onResume()方法时,在OnPause方法回调以前是不会被杀死的。
正如后面的章节:进程和生命周期,一个没有定义为“killable”的activity仍然能够被系统结束,但这时会发生在特殊状况下,好比没有其余资源时。
保存activity的状态
当系统(而不是用户)关闭一个activity来节省内存时,用户但愿再次启动activity时会回到当时的状态。
为了在activity被杀死以前捕获他的状态,你能够实现 onSaveInstanceState()方法,Android会在一个activity将要被关闭时调用这个方法,也就是在onPause()方法以前。他回传递给方法一个Bandle对象,你能够用key-value的方式保存你的数据。当activity再次运行时。这个Bandle对象会传递给onCreate()方法、onStart()方法、onRestoreInstanceState()方法。这几个方法都能重建当时的activity状态。
不像onPause()和刚才讨论的其余几个方法,onSaveInstanceState()和onRestoreInstanceState()方法不是生命周期方法。不是否是总被调用。例如:Android在activity将要被系统销毁以前调用onSaveInstanceState()方法,当activity实例被用户的操做销毁时(例如按下Back键),是不会调用这个方法的。这种状况下没有理由保存他的状态。
Coordinating activities
当一个activity启动了另外一个activity,他们都经历了生命周期的转换。一个暂停了或者结束了,其余的activity启动。一种状况你可能须要调节这些activity:
生命周期方法的回调顺序都是定义好的,尤为当两个activity在同一进程下:
1.当前运行的activity的onPause()方法被调用。
2.而后将要运行的activity的onCreate()、onStart()、onResume()方法被依次调用。
3.而后,若是将要运行的activity不太可见,那么onstop()方法会被调用。
2、Service的生命周期:
有了 Service 类咱们如何启动他呢,有两种方法:
• Context.startService()
• Context.bindService()
1. 在同一个应用任何地方调用 startService() 方法就能启动 Service 了,而后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外若是一个 Service 已经被启动,其余代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会从新执行一次 onStart() 。
2. 另一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,若是调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你能够从这里返回一个实现了 IBind 接口的类,在客户端操做这个类就能和这个服务通讯了,好比获得 Service 运行的状态或其余操做。若是 Service 尚未运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。
总结:
1. startService()的目的是回调onStart()方法,onCreate() 方法是在Service不存在的时候调用的,若是Service存在(例如以前调用了bindService,那么Service的onCreate方法已经调用了)那么startService()将跳过onCreate() 方法。
2. bindService()目的是回调onBind()方法,它的做用是在Service和调用者之间创建一个桥梁,并不负责更多的工做(例如一个Service须要链接服务器的操做),通常使用bindService来绑定到一个现有的Service(即经过StartService启动的服务)。
因为Service 的onStart()方法只有在startService()启动Service的状况下才调用,故使用onStart()的时候要注意这点。
与 Service 通讯而且让它持续运行
若是咱们想保持和 Service 的通讯,又不想让 Service 随着 Activity 退出而退出呢?你能够先 startService() 而后再 bindService() 。当你不须要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就能够既保持和 Service 的通讯,也不会随着 Activity 销毁而销毁了。
提升 Service 优先级
Android 系统对于内存管理有本身的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统以为当前的资源很是有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。若是你的 Service 碰上了这种状况,多半会先被杀掉。但若是你增长 Service 的优先级就能让他多留一会,咱们能够用 setForeground(true) 来设置 Service 的优先级。
为何是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 通常被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 相似优先级获得了必定的提升。当让这并不能保证你得 Service 永远不被杀掉,只是提升了他的优先级。
3、android的service的生命周期与activity相似,可是有一些不一样:
onCreate和onStart是不一样的
经过从客户端调用Context.startService(Intent)方法咱们能够启动一个服务。若是这个服务尚未运行,Android将启动它而且在onCreate方法以后调用它的onStart方法。若是这个服务已经在运行,那么它的onStart方法将被新的Intent再次调用。因此对于单个运行的Service它的onStart方法被反复调用是彻底可能的而且是很正常的。
onResume、onPause以及onStop是不须要的
回调一个服务一般是没有用户界面的,因此咱们也就不须要onPause、onResume或者onStop方法了。不管什么时候一个运行中的Service它老是在后台运行。
onBind
若是一个客户端须要持久的链接到一个服务,那么他能够调用Context.bindService方法。若是这个服务没有运行方法将经过调用onCreate方法去建立这个服务但并不调用onStart方法来启动它。相反,onBind方法将被客户端的Intent调用,而且它返回一个IBind对象以便客户端稍后能够调用这个服务。同一服务被客户端同时启动和绑定是很正常的。
onDestroy
与Activity同样,当一个服务被结束是onDestroy方法将会被调用。当没有客户端启动或绑定到一个服务时Android将终结这个服务。与不少Activity时的状况同样,当内存很低的时候Android也可能会终结一个服务。若是这种状况发生,Android也可能在内存够用的时候尝试启动被终止的服务,因此你的服务必须为重启持久保存信息,而且最好在onStart方法内来作。 服务器
--------------------------------------------------------------------------------------------------网络
activity的生命周期函数
oncreate(Bundle savedInstanceState):在activity第一次被建立的时候调用。这里是你作全部初始化设置的地方──建立视图、绑定数据至列表等。若是曾经有状态记录,则调用此方法时会传入一个包含着此activity之前状态的包对象作为参数 动画
onRestart():在activity中止后,在再次启动以前被调用。 spa
onStart():当activity正要变得为用户所见时被调用。线程
onResume():在activity开始与用户进行交互以前被调用。此时activity位于堆栈顶部,并接受用户输入。 对象
onPause():当系统将要启动另外一个activity时调用。此方法主要用来将未保存的变化进行持久化,中止相似动画这样耗费CPU的动做等。这一切动做应该在短期内完成,由于下一个activity必须等到此方法返回后才会继续。 blog
onStop():当activity再也不为用户可见时调用此方法。这可能发生在它被销毁或者另外一个activity(多是现存的或者是新的)回到运行状态并覆盖了它。
onDestroy():在activity销毁前调用。这是activity接收的最后一个调用。这可能发生在activity结束(调用了它的 finish() 方法)或者由于系统须要空间因此临时的销毁了此acitivity的实例时。你能够用isFinishing() 方法来区分这两种状况。
协调activity
当一个activity启动了另一个的时候,它们都会经历生命周期变化。一个会暂停乃至中止,而另外一个则启动。这种状况下,你可能须要协调好这些activity:
生命周期回调顺序是已经定义好的,尤为是在两个activity在同一个进程内的状况下:
1. 调用当前activity的 onPause() 方法。
2. 接着,顺序调用新启动activity的onCreate()、 onStart()和onResume()方法。
3. 而后,若是启动的activity再也不于屏幕上可见,则调用它的onStop()方法。
总之:一、Activity 从建立到进入运行态所触发的事件 onCreate()-->onStart-->onResume()
二、从运行态到中止态所触发的事件 onPause()--->onStop()
三、从中止态到运行态所触发事件 onRestart()-->onStart()--->onResume()
四、从运行态到暂停态所触发事件 onPause()
五、从暂停态到运行态所触发事件 onResume()
横竖屏幕切换生命周期
1.不设置Activity的android:configChanges时,切屏会从新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次.
2.设置Activity的android:configChanges="orientation"时,切屏仍是会从新调用各个生命周期,切横、竖屏时只会执行一次.
3.设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会从新调用各个生命周期,只会执行onConfigurationChanged方法.
service的生命周期
启动Service时可调用startService和bindService()方法来启动,用这两种方法启动的Service的生命周期是不一样的。
Service的生命周期只有onCreate,onStart和onDestroy,没有onResume,onPause和onStop,大多数时间Service都是运行的,但在严重的内存压力下它也可能被系统kill,若是被kill,系统会在稍后尝试从新启动这个Service
Service的调用
途径一:
调用Context.startService()启动Service,调用Context.stopService()或Service.stopSelf()或Service.stopSelfResult()关闭Service的调用。
Service生命周期分析:
注:onCreate,onStart(),onDestroy()是Service生命周期相关的方法
当Context.startService()启动Service时,若是Service自己没有运行,则调用onCreate()->onStart()完成Service启动。若是Service已经运行,则只调用onStart(),onStart()能够屡次被调用。
Service关闭必须调用Context.stopService()或Service.stopSelf()或Service.stopSelfResult()方法,关闭以前调用onDestroy()方法,不然若是Context直接退出而没有中止Service的话,Service会一直在后台运行。该Service的调用者只能再启动后经过stopService关闭Service。
生命周期顺序为:onCreate()->onStart()->onDestroy()
途径二:
调用Context.bindService()进行初始化绑定,使用Context.unbindService()取消绑定,因为Service和Context是绑定关系,当Context退出或被销毁时,Service也会相应退出。
Service生命周期分析:
调用Context.bindService()时,Service会经历onCreate->onBind(),onBind将返回给客户端一个IBind实例,IBind容许客户端回调服务的方法。此时Context和Service是绑定在一块儿的,Context退出了,Service调用onUnbind()->onDestroy()相应退出。
生命周期顺序为:onCreate->onBind(只一次,不可屡次绑定)->onUnbind->onDestroy()
BroadcastReceiver只能经过startService启动Service,由于广播自己生命周期很短,bind的话没有意义
果不是经过bindService建立的服务(但仍然经过bindService获得了服务对象),就可能unbindService后还在运行,不然应该是结束掉了。