一个服务(Service)是一个应用的组件,其可以在后台执行长时间的操作,而且不提供UI。其他应用组件可以开启一个服务,该服务将会在后台一直运行,纵使用户切换到了其他应用。另外,一个组件可以捆绑到服务上,来与其交互,甚至执行IPC。例如,一个服务可以执行网络链接、播放音乐、执行I/O或者和一个内容提供者(Content Provider)交互,都是在后台运行。
大致的意思是,
一个服务(service)运行在主线程中,服务并不创建自己的线程,也不在隔离进程中运行(除非你指定)。这意味着,如果你的服务要执行CPU费时操作或阻塞操作,你需要在服务中创建新的线程来执行该操作。使用其他线程,可以避免ANR错误,保证应用的主线程可以与用户交互。
看到了吧。虽然service是在后台执行,但是还是在主线程运行的,而主线程是什么呢?就是UI线程,负责屏幕事件的分发和相应,如果在service中执行长时间的操作,就会造成UI线程阻塞,屏幕无响应(无法分发屏幕事件),甚至出现ANR(Application Not Responding)现象。
简单总结一下,
1. 如果你仅仅需要执行后台任务,并不需要和用户交互,此时你可以使用service;
2. 如果你需要在主线程在执行任务,并且当需要和用户交互的时候,此时你可以选择新建一个thread而非service,例如,如果你仅仅需要在activity运行的时候播放音乐,你可以选择在Activity的onCreate方法中新建线程,在onStart方法中运行,在onStop方法中停止。或者,可以采用 AsyncTask或Handler线程。
或许,你会疑问,既然 service并不能执行执行耗时的后台任务,那么为什么还会存在service呢。
其实大家不要把后台和子线程联系在一起就行了,这是两个完全不同的概念。Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,前面不是刚刚验证过Service是运行在主线程里的么?在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。
额,既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。
————————————————
版权声明:本文为CSDN博主「fabowang」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014088294/article/details/49907385