android service与子线程之浅谈

来源:互联网 发布:衣冠南渡 知乎 编辑:程序博客网 时间:2024/04/30 08:51
最近在做一个android的项目,有一个操作是首先将接收的数据处理分析,然后将处理过的数据存储到数据库中。这将是一个十分耗时的工作。我直接将这一操作写在了UI主线程中。结果log中提示不要把耗时的工作在主线程中完成。于是在网上查阅了一下,发现网上有两种说法:一种说写到一个service中去,一种则是开启子线程。于是我就模糊了,到底应该选择哪一种呢?这 里首先应该清楚什么是service,什么是子线程,以及二者的区别。以下是我从网上整理出来的。
 
服务不是单一的进程。服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中。
服务不是线程。可以在线程中工作。在应用中,如果是长时间的在后台运行,而且不需要交互的情况下,使用服务。同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需需要长时间运行的情况下使用线程。如果任务占用CPU时间多,资源大的情况下,要使用线程
。”
     这段文字让我最终决定使用线程。因为服务也是工作在主线程中的,如果服务中要执行耗时的工作也是会阻塞主线程,所以得用主线程。
 
如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成.这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束,BroadcastReceiver就先结束了.BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程).如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死.所以采用子线程来解决是不可靠的.”
 
     当看到上面这段文字后,我曾武断地认为我应该选择服务。但是我们没有想到我定义的BroadcastReceiver是在主线程定义的,所以是不会出现上面的情况。
 
下面就来复习一下service和子线程的一些需要注意的地方。
service:
开启服务的2种方法
        1.  在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。
 
        2. 另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。
如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?你可以先 startService() 然后再 bindService() 。当你不需要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。
 
 
子线程:
       如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。
       当线程的run()方法执行完,或者被强制性地终止,就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
sleep是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。
结束一个进程一般就是要保证run函数能够执行完,但是如果线程处于sleep、wait、join的状态的时候,则不行,可用interrupt来结束线程。
       每个Thread都有一个中断状状态,默认为false。可以通过Thread对象的isInterrupted()方法来判断该线程的中断状态。可以通过Thread对象的interrupt()方法将中断状态设置为true。当一个线程处于sleep、wait、join这三种状态之一的时候,如果此时他的中断状态为true,那么它就会抛出一个InterruptedException的异常,并将中断状态重新设置为false。

原文链接:http://www.360doc.com/content/14/0319/20/12928831_361969514.shtml

0 0