Service高级进阶

来源:互联网 发布:mac pretty boy 编辑:程序博客网 时间:2024/06/08 07:39

        最近在做一个音乐播放的功能,需要使用service来进行播放,这里谈谈使用service的一些点吧。

首先,前台与后台交互的大致过程,上图



Tips:

        service是运行在主线程里的,如果直接在service中处理一些耗时的逻辑,就会导致程序ANR(Application Not Responding)。应该在service中开启线程去执行耗时的任务,这样就可以有效地避免ANR的出现。也就是说在service里创建一个子线程,然后在这里处理耗时的逻辑就可以了。

既然在service里创建子线程,为什么不直接在activity里创建?
    1、因为activity很难对thread进行控制,当activity被销毁后,就没有任何其他的办法可以再重新获取到之前创建的子线程的实例。
    2、在一个activity中创建的子线程,另一个activity无法对其进行操作。
      service就不同了,所以的activity都可以与service进行关联,然后可以很方便地操作其中的方法,即使activity被销毁了,
      之后只要重新与service建立关联,就又能够获取到原有的service中Binder的实例。
      因此,使用service来处理后台任务。

     另一方面,service几乎都是在后台运行的,但其系统优先级还是比较低的,当系统出现内存不足时,

就有可能会回收掉正在后台运行的service。如果你希望service可以一直保持运行的状态,不会由于系统
内存不足的原因导致被回收,就可以考虑使用前台service。

前台service与普通service的最大区别:
它会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,
非常类似于通知的效果。当然有时候可能不仅仅是为了防止service被回收才使用前台service,有些项目由于特殊的需求会要求使用前台service,如墨迹天气,它的service在后台更新天气数据的同时,还会在系统状态栏一直显示当前
天气的信息。

线程池:

写程序时有些异步程序只执行一遍就不再需要了,为了方便经常会写下面的代码,

new Thread(new Runnable() {     @Override    public void run()      {        // TODO Auto-generated method stub     }}).start();
这样new出来的匿名对象会存在一些问题;
 1、由于是匿名的,无法对它进行管理。
 2、如果需要多次执行这个操作就new多次,可能创建多个,占用系统资源。

       a、线程的创建和销毁都需要时间,当有大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将导致性能上的缺失。

       b、大量的线程创建、执行和销毁是非常耗cpu和内存的,这样将直接影响系统的吞吐量,导致性能急剧下降,如果内存资源占用的比较多,还很可能造成OOM。

       c、大量的线程的创建和销毁很容易导致GC频繁的执行,从而发生内存抖动现象,而发生了内存抖动,对于移动端来说,最大的影响就是造成界面卡顿。

 3、无法执行更多的操作。

    而使用线程池(好处):

1、线程的创建和销毁由线程池维护,一个线程在完成任务后并不会立即销毁,而是由后续的任务复用这个线程,从而减少线程的创建和销毁,节约系统的开销。

2、线程池旨在线程的复用,这就可以节约我们用以往的方式创建线程和销毁所消耗的时间,减少线程频繁调度的开销,从而节约系统资源,提高系统吞吐量。

3、在执行大量异步任务时提高了性能。

4、Java内置的一套ExecutorService线程池相关的api,可以更方便的控制线程的最大并发数、线程的定时任务、单线程的顺序执行等。

线程池的分类和使用可参考:http://android.jobbole.com/82092/



0 0
原创粉丝点击