不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Thread之间没有任何关系!

之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的,你还会觉得它和Thread有什么关系吗?让我们看一下这个残酷的事实吧。

在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:

Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  

然后在MyService的onCreate()方法里也加入一行打印当前线程id的语句:

Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());  

现在重新运行一下程序,并点击Start Service按钮,会看到如下打印日志:

可以看到,它们的线程id完全是一样的,由此证实了Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定会出现ANR的。

你可能会惊呼,这不是坑爹么!?那我要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,完全不需要担心无法对后台任务进行控制的情况。

一个比较标准的Service就可以写成:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
} class MyBinder extends Binder { public void startDownload() {
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
} }

最新文章

  1. USACO . Greedy Gift Givers
  2. Document对象操作、样式、属性、效果、
  3. SuperMap iClient 7C——网络客户端GIS开发平台 产品新特性
  4. Predicting purchase behavior from social media-www2013
  5. jsp学习---使用jsp和JavaBean实现超简单网页计算器
  6. [ActionScript 3.0] LocalConnection示例
  7. ANR
  8. hdu4085 Peach Blossom Spring 斯坦纳树,状态dp
  9. 【Python】一个python实例:给重要的文件创建备份.摘自crossin-python简明教程
  10. Ping pong(树状数组经典)
  11. python的函数式编程
  12. http验证
  13. mybatis 中使用oracle merger into
  14. lecture4特征提取-七月在线-cv
  15. tf.pad(one_hot_encoding, [[0, 0], [1, 0]], mode='CONSTANT')
  16. 3d打印机的软件系统组成部分
  17. jQuery Validation让验证变得如此easy(二)
  18. 【安全开发】PHP安全编码规范
  19. 浅谈 React
  20. Java并发编程笔记之LongAdder和LongAccumulator源码探究

热门文章

  1. react-native 学习
  2. 使用Eclipse自带Web Service插件(Axis1.4)生成Web Service服务端/客户端
  3. HDU 1430 魔板(康托展开+BFS+预处理)
  4. CSS权威指南 - 层叠
  5. [办公自动化]skydrive onedrive
  6. PHP+jQuery 注册模块的改进之二:激活链接的URL设置与有效期
  7. python 调用系统命令
  8. typecho插件编写教程1 - 从HelloWorld说起
  9. java-冒泡排序
  10. 关于C和C++动态链接库的几个问题