深入剖析Android系统中Service和IntentService的区别
android中的service是用于后台服务的,当应用程序被挂到后台的时候,问了保证应用某些组件仍然可以工作而引入了service这个概念,那么这里面要强调的是service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在service中编写耗时的逻辑和操作,否则会引起anr。
那么我们当我们编写的耗时逻辑,不得不被service来管理的时候,就需要引入intentservice,intentservice是继承service的,那么它包含了service的全部特性,当然也包含service的生命周期,那么与service不同的是,intentservice在执行oncreate操作的时候,内部开了一个线程,去你执行你的耗时操作。
service本身存在两个问题:
(1)service不会专门启动一条单独的进程,service与它所在的应用位于同一个进程。
(2)service也不是专门新的一条线程,不应该在service中处理耗时的操作。
intentservice很好的弥补了这一点:
(1)intentservice会创建单独的worker线程来处理所有的intent请求。
(2)intentservice会创建单独的worker线程来处理onhandleintent()方法实现的代码。
(3)当所有的请求处理完之后,intentservice会自动停止。
(4)为service的onbind()方法提供了默认的实现,返回null。
(5)为service的onstartcommand()方法提供了默认的实现,该实现会将请求intent添加到队列中。
所以对intentservice的使用就是:继承intentservice,重写onhandleintent()方法即可。
tips:
(1)intentservice也必须在manifest中声明。
(2)实现类的构造方法必须实现默认的构造方法。
这里我 需要解释以下几个方法,也许大家都已经很清楚了,不过为了抛砖引玉,我还是要提一嘴。
service中提供了一个方法:
public int onstartcommand(intent intent, int flags, int startid) { onstart(intent, startid); return mstartcompatibility ? start_sticky_compatibility : start_sticky; }
这个方法的具体含义是,当你的需要这个service启动的时候,或者调用这个servcie的时候,那么这个方法首先是要被回调的。
同时intentservice中提供了这么一个方法:
protected abstract void onhandleintent(intent intent);
这是一个抽象方法,也就是说具体的实现需要被延伸到子类。
子类的声明:
public class chargeservice extends intentservice
上面提到过intentservice是继承service的,那么这个子类也肯定继承service,那么onhandleintent()方法是什么时候被调用的呢?让我们具体看intentservice的内部实现:
private final class servicehandler extends handler { public servicehandler(looper looper) { super(looper); } @override public void handlemessage(message msg) { onhandleintent((intent)msg.obj); stopself(msg.arg1); } } /** * creates an intentservice. invoked by your subclass's constructor. * * @param name used to name the worker thread, important only for debugging. */ public intentservice(string name) { super(); mname = name; } /** * sets intent redelivery preferences. usually called from the constructor * with your preferred semantics. * * <p>if enabled is true, * {@link #onstartcommand(intent, int, int)} will return * {@link service#start_redeliver_intent}, so if this process dies before * {@link #onhandleintent(intent)} returns, the process will be restarted * and the intent redelivered. if multiple intents have been sent, only * the most recent one is guaranteed to be redelivered. * * <p>if enabled is false (the default), * {@link #onstartcommand(intent, int, int)} will return * {@link service#start_not_sticky}, and if the process dies, the intent * dies along with it. */ public void setintentredelivery(boolean enabled) { mredelivery = enabled; } @override public void oncreate() { // todo: it would be nice to have an option to hold a partial wakelock // during processing, and to have a static startservice(context, intent) // method that would launch the service & hand off a wakelock. super.oncreate(); handlerthread thread = new handlerthread("intentservice[" + mname + "]"); thread.start(); mservicelooper = thread.getlooper(); mservicehandler = new servicehandler(mservicelooper); } @override public void onstart(intent intent, int startid) { message msg = mservicehandler.obtainmessage(); msg.arg1 = startid; msg.obj = intent; mservicehandler.sendmessage(msg); }
在这里我们可以清楚的看到其实intentservice在执行oncreate的方法的时候,其实开了一个线程handlerthread,并获得了当前线程队列管理的looper,并且在onstart的时候,把消息置入了消息队列,
@override public void handlemessage(message msg) { onhandleintent((intent)msg.obj); stopself(msg.arg1); }
在消息被handler接受并且回调的时候,执行了onhandlerintent方法,该方法的实现是子类去做的。
结论:
intentservice是通过handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生anr的情况。
上一篇: Linux下切分Tomcat的catalina.out日志文件
下一篇: 拉钩网java笔试题分享