Android Service demo例子使用详解\
概述
Service 是 Android 的四大组件之一,它主要的作用是后台执行操作,Activity 属于带有 UI 界面跟用户进行交互,而 Service 则没有 UI 界面,所有的操作都是基于后台运行完成。并且 Service 跟 Activity 一样也是可以由其它的应用程序调用启动的,而且就算用户切换了应用程序,Service 依旧保持运行。一个组件如果与 Service 进行了绑定( bind ),就可以跟 Service 进行数据的交互,并且也可以跟不同的进程之间进行交互 (IPC)。通常会使用到 Service 的情况有进行网络请求,音乐的操控,文件的 I/O 操作等。
启动
Service 通常是通过以下两种方式进行启动
startService
当组件(例如 activity)通过调用 startService() 来启动 Service 的时候。一旦启动后,Service 就会独立的在后台运行,即使调用的组件已经销毁了,Service 还是可以继续在后台运行。 一般情况下,只需要进行一次单独的操作,不需要将操作后的结果返回给调用者的时候,会使用该方式启动 Service 。例如,进行上传或者下载操作的时候,当操作完成后,Service 应该自行调用 stopService() 或 stopSelf() 来结束运行。
bindService
当组件(例如 activity)通过调用 bindService() 来启动 Service 的时候。这种方式提供了 client - service 的接口,可以让调用组件跟 Service 进行发送请求及返回结果的操作(腾云科技ty300.com),设置可以进行进程间的通信 (IPC)。只要有一个组件对该 Service 进行了绑定,那该 Service 就不会销毁。并且多个组件可以同时对一个 Service 进行绑定, 只有在所有进行了绑定的组件都解绑的时候,Service 才会销毁 。
尽管两种方式是分开讨论的,但是并不是互斥的关系,使用 startService 启动了 Service 后,也是可以进行绑定的。
注意: 虽然 Service 是在后台运行,但是其实还是在 主线程 里进行所有的操作的(入门教程qkxue.net)。Service 在启动时除非单独进行了定义否则并没有在单独的线程或者进程了而都是在 主线程 里。所以这表示任何能堵塞主线程的操作(例如音乐的播放或者网络请求)都应该单独开辟新的线程来进行操作,否则很容易出现 ANR 。
方法
在创建一个 Service 时,必须要去继承 Service ,并且要重写父类一些主要的方法来实现功能。以下是主要方法的介绍
onStartCommand()
系统会调用这个函数当某个组件(例如 activity,fragment)通过调用 startService() 启动 Service 时。在该方法被调用后,Service 就会被启动并独立的在后台运行。如果重写了该方法,开发者需要在 Service 执行完操作后自行的调用 stopSelf() 或 stopService() ,来结束 Service。 如果只是会通过绑定的方式 (bind) 的方式来启动 Service 则不需要重写该方法 。
onBind()
系统会调用这个函数当某个组件(例如 activity, fragment)通过调用 bindService() 绑定的方式来启动 Service的时候。在实现这个函数的时候,必须要返回一个 IBinder 的继承类,来与Service 进行通信。这个函数是默认必须要重写的,但是如果不想通过绑定的方式来启动Service,则可以直接返回 null
onCreate()
系统会调用此方法在第一次启动 Service 的时候, 用于初始化一些一次性的变量 。如果Service已经启动了,则此方法就不会再别调用 。
onDestroy()
系统在Service已经不需要准备被销毁的时候会调用此方法。 Service中如有用到thread 、listeners 、receivers等的时候,应该将这些的清理方法写在此方法内 。
以上就是实现一个 Service 中要实现的一些方法。
如果某个组件是通过调用startService()的方式来启动了 Service, 那这个Service就会一直在后台运行直到 Service内部调用 stopSelf()或某个组件调用stopService()来结束该Service。
如果某个组件是通过调用 bindService()的方式来启动了 Service,那这个 Service 就会一直在后台运行直到该组件与其解绑。Service在没有任何组件绑定的时候,系统会将其销毁
下面的环节,将介绍如果通过上面讲述的两种方式来创建 Service
在 Manifest 里声明 Service
类似于 Activity ,所有的 Service 都要在 Manifest 里面进行声明,如下:
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
通过在 <service> 标签里将 android:exported 设置为 false。可以防止其他的程序来启动你的 Service。
通过started 方式来启动 Service组件(例如 activity, fragment) 通过调用 startService() 方法,系统随之调用 onStartCommand() 方法来实现 started 方式启动 Service。
当Service以该形式启动后,Service的整个生命周期是完全独立的,即便启动Service的组件已经被销毁了,Service还是可以在后台无限的运行的。但开发者应该在Service中的操作执行完成后,调用stopSelf()或其它组件调用stopService()的方式来结束该Service。
程序组件(例如 activity)可以通过传递一个 Intent 给startService() ,来实现组件与Service之前的数据传递。Service是通过系统调用的onStartCommand()方法接受传递的Intent ,完成整个数据传递过程。
注意: Service 本身默认是运行在主线程里的,所以如果在 Service 要进行一些会堵塞线程的操作,一定要将这些操作放在一个新的线程里。
Android 的框架提供了 IntentService 来满足后台运行异步线程的需求。
IntentService
IntentService 是 Service 的子类,并且所有的请求操作都是在异步线程里。如果不需要 Service 来同时处理多个请求的话,IntentService 将会是最佳的选择。只需要继承并重写 IntentService 中的 onHandleIntent() 方法,就可以对接受到的 Intent 做后台的异步线程操作了。
IntentService 提供了如下的几个功能:
会创建一个异步线程来处理所有从程序主线程发送到 onStartCommand() 的 intents 。
创建了一个队列池来保证每次只有一个 Intent 传递到 onHandleIntent() 方法中,避免了多线程问题。
提供默认 onBind() 方法的实现,返回 null
提供默认 onStartCommand() 方法的实现,将收到的 intent 放到队列池中,然后再交由 onHandleIntent() 做处理
所有开发者只需要实现 onHandleIntent() 关注于 Service 要进行的操作即可。关于更多的 IntentService 实用技巧,请查看此 文章 。
如果开发者需要重写其他的一些方法,例如 onCreate(), onStartCommand(), 和 onDestroy(),请保证调用父类的实现,这样可以保证 IntentService 能够正确的来处理线程的生命周期。例如:
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); return super.onStartCommand(intent,flags,startId);
}
系统回收资源问题
当系统内存不足的时候,系统会强制回收一些 Activity 和 Service 来获取更多的资源给那些用户正在交互的程序或页面。这就要求 Service 能够自动重启当资源充足的时候。这个功能是通过 onStartCommand() 的返回值来实现的
START_NOT_STICKY
当系统因回收资源而销毁了 Service,当资源再次充足时不自动启动 Service。 除非还有为处理的 Intent 准备发送 。当你的程序可以很容易的重新开启未完成的操作时,这是最安全的避免 Service 在不必要的情况下启动的选项。
START_STICKY
当系统因回收资源而销毁了Service,当资源再次充足时自动启动Service,并且再次调用onStartCommand()方法,但是不会传递最后一次的 Intent,相反系统在回调onStartCommand()的时候会传一个空Intent 。除非还有为处理的Intent准备发送 。
稿源:勤快学QKXue.NET
扩展阅读
http://qkxue.net/info/24418/Android-Service