也许我们很难会把这两者牵连到一起,毕竟有点八杆子打不着,但是某个xx冷不丁的问一下你,你的第一时间反应是什么?是不是也有点不知所措,毕竟我们都是撸码撸的有自信的人,对于这样的问题,总是带有一丝的不确定性,回答的也是朝着自己自信的一面去,总得说出个子丑寅卯的关系,但其实,往往会被我们的自信蒙蔽,就如今天的这个疑问,我要告诉你的是Service与Thread真的一点关系也没有!
什么是Service呢?在Android中它是四大组件之一,用户是看不到的,也就是说并不与用户产生UI交互,使用Service可以在后台执行长时间的操作;什么是Thread?Thread是程序执行的最小单位,可以使用它来执行一些异步的操作。Thread可以肯定的是,它是独立运行的,也就是说在A这个Activity你启动了一个Thread,A这个Activity,finish之后,Thread如果没有停止,或者run方法没有执行完毕的话,那么这个Thread是一直执行的,由于它是独立运行的,再想办法去控制这个Thread,那是不可能的,当然了你可以杀死进程。相比较来说,在Service去执行控制这个Thread,便能解决这个问题,因为任何Activ ity都可以控制同一个Service。
其实我们最大的疑惑莫过于,认为Thread也可以在后台执行,显然这是错误的,你觉得在一个Activity里new一个Thread,在run方法里执行一些定时耗时操作,应用退出进程不死的情况下,run方法里还会执行吗?显然是不会的,就比如如下的操作,应用一旦退出,只保留进程,则打印立即会停止。
privateinta; privatevoidcreateThread() { Threadthread=newThread() { publicvoidrun() { super.run(); while (a<50) { a=a+1; Log.i("MainActivity", a+"==="); try { Thread.sleep(1000); } catch (InterruptedExceptione) { e.printStackTrace(); } } } }; thread.start(); }
当然了我们可以结合Service解决这个问题,在Service去做上面的这些事情,那么只要进程不死,条件满足,run方法则会一直执行,以至于Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人和Thread产生混淆,其实我想说的是,Service是在主线程里运行的。
我们在Activity的onCreate方法里和Service里的onCreate分别打印这样一句话:
Log.i("ServiceId", "MainActivity"+Thread.currentThread().getId() +"=="+Thread.currentThread().getName());
在看打印的log日志:
01-1215:11:18.32930721-30721/com.ming.abner.serviceaddthreadI/ServiceId: MainActivity1==main01-1215:11:22.56930721-30721/com.ming.abner.serviceaddthreadI/ServiceId: MainActivity1==main
通过上面的信息,我们不难发现,线程id都是1,是一样的,并且都是在main主线程里,显而可见我们是不能在Service去执行耗时操作的,不然会出现ANR。
最后要告诉同志们的是,千万不要把后台和子线程联系到一起,他们是完全不同的概念。即便我们的应用退出,只要其进程还在,那么Service就可以继续运行,比如我们在开发当中,有一些需要时时向服务端传递状态,需要和服务器之间保持着心跳连接,那么就可以用Service来实现,为来使其不阻塞主线程,我们可以创建个子线程,来处理相关逻辑。
既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这个前边也已经说过了,Thread是独立运行的,其它Activity并不能对其操作,但是Service不同,所有的Activity都可以与Service进行关联,即便Activity销毁了,我们也可以重新来与Service建立关联。