android intentservice可以绑定吗,Android IntentService使用介绍以及原理分析

简介

在Android应用的程序中,普通的Service中的代码是运行在主线程中的,如果想要在Service中做些耗时的操作,就很容易出现ANR的现象(大概是20秒),那么我们经常的做法就是,在onStartCommon方法中开启一个子线程然后内部执行耗时的操作,在执行完毕后如果需要自动停止服务需要在子线程的run方法中调用stopSelf()来停止服务。

虽说在Service中执行耗时的代码可以很容易的实现,但是Android提供的IntentService类可以很方便的解决了自己开启线程和手动停止服务的问题。接下来看看IntentService的使用步骤。

使用步骤

IntentService是一个抽象类内部有一个抽象的方法 handleIntent(),继承至Service类.所以使用它需要继承它实现抽象方法。

public class MyIntentService extends IntentService {

private static final String TAG = "MyIntentService";

public MyIntentService() {

super("MyIntentService");

}

@Override

protected void onHandleIntent(Intent intent) {

//在这里通过intent携带的数据,开进行任务的操作。

Log.d(TAG, "onHandleIntent: " + Thread.currentThread().getName());

}

@Override

public void onDestroy() {

super.onDestroy();

Log.d(TAG, "onDestroy: ");

}

}

然后调用StartService()启动异步后台服务类 IntentService。

startService.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(MainActivity.this, MyIntentService.class);

startService(intent);

}

});

源码分析

服务启动的过程中,会去执行服务的生命周期方法,在开启服务的时候,有两种方式,分别为startService和bindService

startService方式启动,生命周期方法执行的顺序是 onCreate(),onStartCommand() onStart() onDestroy(),按照生命周期执行顺序我们查看IntentService的源码

// onCreate方法的分析

@Override

public void onCreate() {

super.onCreate();

HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");

//创建了一个Looper对象 & MessageQueue对象 调用了Looper.loop方法

thread.start();

// 获取到HandlerThread中创建好的Looper对象。

mServiceLooper = thread.getLooper();

//ServiceHandler extends Handler,绑定了HandlerThread中的Looper对象 ;那个线程调用了Looper中的loop方法,Handler的dispatchMessage方法就运行在那个线程中。

mServiceHandler = new ServiceHandler(mServiceLooper);

}

//onStartCommand()方法分析

public int onStartCommand(@Nullable Intent intent, int flags, int startId) {

// 调用了onStart方法

onStart(intent, startId);

return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;

}

//onStart方法

public void onStart(@Nullable Intent intent, int startId) {

//在这里构造了一个消息对象

Message msg = mServiceHandler.obtainMessage();

msg.arg1 = startId;

//将intent 包装到了Message的obj中,

msg.obj = intent;

//然后调用sendMessage()将消息插入到队列中。

//最终消息被取出然后被分发,最后调用了handleMessage()来处理这个消息

mServiceHandler.sendMessage(msg);

}

//ServiceHandler handleMessage方法的分析

private final class ServiceHandler extends Handler {

public ServiceHandler(Looper looper) {

super(looper);

}

@Override

public void handleMessage(Message msg) {

//SeriviceHandler 的handleMessage()方法中 将接受到的消息交给onHandleIntent来处理,onHandleIntent方法就是我们实现的方法,获取到Intent,处理任务。

onHandleIntent((Intent) msg.obj);

//执行完 结束服务

stopSelf(msg.arg1);

}

}

// onDestroy()方法的处理

@Override

public void onDestroy() {

//将消息队列中的所有消息给移除,包括处理中的和未处理的

mServiceLooper.quit();

}

总结说来就是,开启服务执行onCreate()方法,方法中创建好了一个子线程(HandlerThread),(子线程中创建好了一个Looper对象同时创建好了一个MessagqQueue消息队列,然后开启轮询消息队列。),内部创建好的Handler与子线程中的Looper对象绑定。onCreate只有在服务第一次创建的时候才会调用,之后每次调用都只会执行onStartCommand方法,在此方法中我们构建好了一个Message对象,并且将传递进来的Intent封装在Mesage,一起发送到消息队列中。经过轮询将消息分发到Handler的handleMessage中处理,此时获取到Message中携带的Intent传递给我们实现好的handleIntent方法中进行任务的处理,处理完毕自动调用StopSlef来结束服务。在onDestroy方法会把所有消息都给退出。

上文中我们分析了startService方法启动的服务,那bindService方式启动服务的分析如下(绑定服务,建立长期通信),bindService启动会执行 onCreate -> onBind -> onUnBind -> onDestroy方法。

//onCreate方法上文中已经分析

//onBind()

public IBinder onBind(Intent intent) {

//直接返回null了。那么不对会Mesage对象和发送消息到队列中,

//然后回调handleIntent方法了。

return null;

}

所以bindService方式启动服务,不会进行多线程的操作。

问题记录

简单描述一下IntentService

IntentService是一个特殊的Service类,是实现了多线程处理异步请求的一个服务类,在handleIntent方法中进行耗时的操作,如果有多个耗时的操作任务,会按照顺序去一个一个的执行,执行完一个关闭一个。

在源码handleMessage方法中为什么执行完handleIntent方法会去调用带参数的stopSelf()

因为stopSelf()的执行会立刻将服务停止掉,而带参数的stopSelf(int startId)会在所有任务执行完毕后将服务给停止。通常情况下调用stopSelf(int satrtId)方法不会立刻去执行停止服务的操作,会去判断最近执行任务的次数是否和startId相等,如果相等就立刻执行停止服务的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值