android-----IntentService源码分析

        上一篇我们介绍了HandlerThread的用法,这一篇将从源码的角度来学习下IntentService的用法,其实IntentService是对HandlerThread的一种封装,又由于他本身是Service,所以很自然他也有Service的一些特点,比如他可以在后台使用,并且优先级较高,不容易被杀死,下面我们看看IntentService的源码;

        首先查看他的类结构

public abstract class IntentService extends Service {}
        发现他是继承自Service的抽象类,所以我们要想使用它的话必须实现这个类;

        接着很自然想到要看他的onCreate方法了,因为是Service嘛:

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

        可以发现第8行创建了HandlerThread对象,第9行调用了HandlerThread的start方法,这个方法会执行HandlerThread的run方法,在run方法里面会创建Looper对象,并且调用Looper对象的loop方法,接着第11行获得了HandlerThread里面创建的Looper对象,并且将其赋给了mServiceLooper,第12行以mServiceLooper为参数创建了Handler对象,这个就是我们使用HandlerThread的过程,所以说IntentService的真正实现其实就是HandlerThread罢了;

        熟悉Service生命周期的都知道执行完onCreate方法之后,在调用startService之后将会执行onStartCommand方法,我们来看看IntentService里面的onStartCommand方法:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
        可以发现这个方法的第一句其实调用的是onStart方法,我们来看看onStart方法:

@Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
        这个方法首先通过handler的obtainMessage方法从消息池中获得一个Mrssage对象,接着将Intent值赋给该Message对象的obj属性,这里的Intent就是我们在startService的时候传入的Intent值,截止调用Handler对象的sendMessage方法,很自然就会执行 mServiceHandler的handleMessage方法了:

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);
        }
    }
        在handleMessage中首先执行的是onHandleIntent方法,这个方法如下:

protected abstract void onHandleIntent(Intent intent);
        也就是说在IntentService里面这个方法是并没有实现的,需要我们在实现IntentService的时候自己实现,这个方法传入的参数就是我们startService的时候传入的Intent参数,最后在onHandleIntent执行结束之后就会执行stopSelf方法了,这个方法有个叫startId的参数,我们在停止服务的时候会先查看开启服务的次数是否等于startId,如果相等的话才会停止服务,不等的话是不会停止服务的;

        在调用stopSelf停止服务之后就会回调onDestroy方法,在onDestroy方法中,我们会发现调用了Looper的quit方法,进而结束了Looper中的loop死循环;

        还有一点需要注意的就是,我们可能会多次调用startService方法来启动IntentService,但是你要知道startService只是回调的onStartCommand方法,而我们的Handler以及Looper对象是在onCreate方法中创建的,所以也就造成了这些后台任务是串行执行的情况了,因为他们来了只是会放到MessageQueue消息队列中,进而由Looper来拿到他们由handleMessage来进行处理的;

        接下来,我们来使用下IntentService

        首先创建IntentService的实现类MyIntentService

public class MyIntentService extends IntentService {

	public static final String TAG = "com.hzw.messengertest.MyIntentService";
	public MyIntentService()
	{
		super(TAG);
	}
	
	public MyIntentService(String name) {
		super(name);
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		SimpleDateFormat format = new SimpleDateFormat("HH:MM:ss");
		System.out.println(format.format(new Date())+"执行到了"+intent.getExtras()+" 当前执行线程为:  "+Thread.currentThread().getId());
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		SimpleDateFormat format = new SimpleDateFormat("HH:MM:ss");
		System.out.println(format.format(new Date())+"执行了onDestroy");
	}
}

        可以看到我在onHandleIntent中会将当前线程暂停2秒,并且会输出当前执行到的时间,以及当前执行任务线程的ID,同时在onDestroy中也输出了时间;

        接下来定义Activity来开启服务:

public class IntentServiceActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Intent intent = new Intent(this,MyIntentService.class);
		intent.putExtra("intent_1", "intent_1");
		startService(intent);
		intent.putExtra("intent_2", "intent_2");
		startService(intent);
		intent.putExtra("intent_3", "intent_3");
		startService(intent);
	}
}
        可以看到我们创建了一次intent,但是调用了3次startService方法,随后查看输出结果:

   

        可以看到每次执行之间的时间差正好是2秒,并且他们都是同一个线程执行的,原因很简单就是因为MyIntentyService的onCreate方法只执行了1次,而真正执行的线程是HandlerThread,HandlerThread是在onCreate中创建的呐;

        从上面还可以看出来一点,我们并没有执行onDestroy方法,为什么会有他的输出呢?原因就在于,我们在onHandleIntent方法执行结束之后,系统会回调stopSelf方法,而这个方法是会执行onDestroy方法的,这也就导致了IntentService的一个特点的出现,就是当我们的任务执行结束,也就是onHandleIntent执行结束之后,就会停止掉当前IntentService,这点需要注意一下啦!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值