最近学习了一下Service,主要看的官方文档,感觉记忆的东西太多,脑袋一团乱,特此总结一下:
Service的关键点主要有:如何创建一个Service、如何实现控件与Service之间的通信、Started和Bound之间的区别 以及Service的生命周期。
一、Service
Service是一种隐藏的应用控件,它长时间的在后台运行,其他用户可以通过开启或是绑定到一个Service,从而与之进行交互。可以通过自己或是其他控件停止开启的Service,绑定的Service会在没有绑定控件时停止。另外,Service的运行优先级仅比获得焦点的Activity低,所以一般只会在系统资源严重不足的时候被kill。
二、创建Service
要创建一个Service,必须是实例化一个Service的子类,Service本身是一个抽象类。
在子类中,关键是要复写几个重要的回调函数,以此来控制Service的生命周期,以及实现开启或是绑定方式。
1、onCreate()
类似Activity的onCreate(),在Service第一次被创建时,执行这个回调函数,如果该Service已经在运行了,则不调用该函数。
2、onDestroy()
同理,当Service停止不用或被销毁时,系统会调用这个函数来释放资源。
3、onStartCommand(),API5以前的版本是onStart()
如果只想让Service被绑定,就可以不用实现该函数。当实现了改函数, 其他控件可以通过调用startService()
来开启该Service,从此该Service就一直运行,即使创建开启它的控件已经被销毁。此时必须要控制Service的结束,可以在它完成功能后调用stopSelf() 来结束,或是通过其他控件调用stopService() 来结束它。
4、onBind()
该函数必须被实现,如果不允许该Service被绑定,可以在该函数中返回null。其他控件可以通过bindService() 来绑定到该Service,但是这个函数必须返回一个IBinder对象,该对象是客户与Service的交互接口。绑定的Service不用管理它的结束,系统会在没有任何控件绑定它时结束它。
当然,也可以通过继承Service的子类IntentService来创建一个Service的实例。相对于Service,IntentService会创建一个辅助线程来处理传递到onStartCommand()中的所有intents,它会创建一个辅助队列,每次从队列中传递一个intent到onHandleIntent() 中,这样就防止了多线程。而且,在所有intent都处理完后,系统就会结束该Service,所以不用管理它的资源回收。
当实现一个IntentService子类的时候,会得到一个默认的onBind()函数,返回null,以及一个默认的onStartCommand()函数,它将发送Intent到辅助队列,再发送到onHandleIntent() ,也就是说最简单的情况下,只需要实现onHandleIntent()。
三、Service的两种形式
当实现了Service的一个子类,并且在manifest中声明了它之后,我们就可以启动或是绑定这个Service了,当然也可以同时进行这两个动作,只要实现了(二)中的回调函数。
1、Started Service
正如前面所说,其他控件可以通过调用 startService() 来启动一个Service,并通过传递Intent到onStartCommand() 来指定是哪个Service,并与之进行交互。这种形式的Service必须管理它的结束。
2、Bound Service
而绑定到一个Service则是通过调用 bindService() 函数,并传递相应的Intent,并且回调函数onBind()必须返回一个IBinder对象来与客户进行交互。而解除绑定则是调用unbindService() 函数,当没有控件与之绑定时,Service就将被销毁。
四、Service的生命周期
生命周期包括完整周期:创建( onCreate())和销毁( onDestroy()),活动周期:启动( onStartCommand())/绑定( onBind())和停止(onDestroy())/解除绑定( onUnbind()),停止一个Started Service时,没有特别的回调函数,就只有onDestroy()。
五、小结
通过初步学习,了解到Service的创建方式:实现Service子类或是实现IntentService子类;Service的两种形式及区别;以及与Service之间的交互方法:传递Intent,绑定方式下的IBinder对象;Service的生命周期:完整的和活动的。
当大家看到这篇博的时候,我很遗憾的说我们要推倒重来了 因为大多数项目都不大可能只有一个界面,当然你也可以给window-base-app类型的项目额外增加一些UINavigationController或者一些控制器来实现多界面的跳转和交互功能。但是这个成本相对较高,Xcode默认可以创建
新建项目名称
值得庆幸的是我们很多重复的代码我们可以从window-base-app种直接copy过来,我们把原来设计在window.xib中登录界面拖拽到ViewBaseAppViewController.xib中
运行模拟器