Android IntentService


/**

 *
 * 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50274211

 *   @author:【JunTao_sun】
 *
 *
*/



IntentService是Service的子类,是一个通过Context.startService(Intent)启动,

以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的

onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候).

所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),

一次只能执行一个请求.

 

 

    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);
        }
    }
ServiceHandler是IntentService的内部类 是handler的子类 

当有消息被加入消息队列  handlemessage会调用OnHandleIntent函数 处理intent

stopself(int startID) 不同于stopself()会直接停止服务   带参数的它会匹配startID是否一致 再停止服务。

如果同时有多个服务启动请求发送到onStartCommand(),不应该在处理完一个请求后调用stopSelf();

因为在调用此函数销毁service之前,可能service又接收到新的启动请求,如果此时service被销毁,

新的请求将得不到处理。此情况应该调用stopSelf(int startId)。

@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);
    }

在Oncreate方法中 初始化线程HandlerThread 并开始启动 。

初始化ServiceHandler。得到HandlerThread  里的消息轮询器 。

把mServiceLooper消息轮询器 做参数构造一个hanler对象 也就是初始化ServiceHandler。

下边是HandlerThread 和looper的源码 

  @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
looper的:

  public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
 HandlerThread   的run方法 里调用 Looper.prepare(); 由源码可知 sThreadlocal 是成员变量 ThreadLocal类 相当于map变量副本,

如果sThreadlocal 已经有looper了 抛异常 ->一个线程只能有一个looper ,没有则存储在sThreadlocal 。

接着 HandlerThread 里调用looper的静态方法 获得looper.,

  public static Looper myLooper() {
        return sThreadLocal.get();
    }
 public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }
HandlerThread 里有个while 循环 当前线程是活的并mlooper是Null 阻塞 ,等待到mlooper不等于Null返回。


public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
 new ServiceHandler(mServiceLooper) 会调用hanler的三个构造方法

关联一个消息轮询器  此时处理消息的就是HanlerhThread的消息轮询器里的message.


继续回到IntentService的源码

/**
     * You should not override this method for your IntentService. Instead,
     * override {@link #onHandleIntent}, which the system calls when the IntentService
     * receives a start request.
     * @see android.app.Service#onStartCommand
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值是四个常量分别是:

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }
设置是否重新发送意图,当服务被异常Kill掉的时候  

onStartCommand  方法中 调用了onStart函数:

 @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

 

onStart()方法 把消息发送到 ServiceHandler 处理意图 和是否停止服务

不能重写onStartCommand方法 

如果想要对意图进行处理可以 重写onHandleIntent(Intent intent)方法













  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值