前言
源码分析篇,分析过程也参考过各位大神的成果。知识在于分享,学会了就是自己的,有参考过的,也会尽量给出链接(看了很多,可能无法一一给出);希望共同进步,站在巨人肩膀上看世界!
参考:http://blog.csdn.net/smbroe/article/details/45009721
以下用法和源码分析基于android-27(即版本android 8.1.0)
要点总结
1.生命周期onCreate --> onStartCommand --> onStart --> onHandleIntent --> onDestroy
其中onCreate、onStartCommand、onStart、onDestroy运行在ui线程,onHandleIntent运行在子线程;
2.如果每次onHandleIntent执行的时间足够长的话,连续循环启动IntentService的
onCreate只会执行一次,而onStartCommand、onStart则启动几次就执行几次,onHandleIntent也是启动几次就执行几次,onDestroy只执行一次;
对应onHandleIntent来说是串行的,对同一进程内同一IntentService来说必须按序排队依次执行;
即如果IntentService未执行完任务时,不会再次启动新的IntentService,而是会使用原IntentService排队执行任务,全部任务执行完毕后,才退出IntentServie;
3.如果启动IntentService时,前边的任务已经执行结束并退出后,则会再次创建onCreate并执行
4.需要提供无参的构造函数,然后调用父类的有参构造;Service的实例化是系统来完成的,而且系统是用参数为空的构造函数来实例化Service的
5.假设在onHandleIntent中创建handler并执行操作:
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.d(TAG,"onHandleIntent"+" ,"+Thread.currentThread());
Handler temphandler=new Handler(){
@Override
public void handleMessage(Message msg) {
Log.d(TAG,"handleMessage"+" ,"+Thread.currentThread());
}
};
temphandler.sendEmptyMessageDelayed(1,5000);
}
这样handleMessage是不会执行的,因为此时temphandler获取的是intentService中HandlerThread的looper,而在onHandleIntent执行完后,会调用onDestroy退出整个消息队列,所以这边的handleMessage就执行不到了;
如果temphandler是在外部初始化的就可以,默认会拿的mainlooper;
优缺点
优点:
1.与service都运行于ui线程不同,intentService在子线程中处理耗时任务,避免堵塞造成anr;
2.自己维护消息队列,实现排队执行,避免多线程资源同步问题;
3.无需手动停止intentservice,任务都执行完毕后自动销毁;
4.存在已启动的正在使用的intentServie的话,再次启动不会重复创建,而是共用一个节省不必要资源开销
缺点: 1.处理完成之后要通知ui的话,相对麻烦,可能需要使用ui线程的handler或者广播。
使用方法
//创建实现IntentService的子类并在AndroidMainfest.xml中声明
<service android:name=".MyIntentService"></service>
public class MyIntentService extends IntentService{
String TAG="MyIntentService";
public MyIntentService() { //需要提供默认的无参构造函数,然后调用父类的有参构造
this("MyIntentService");
}
public MyIntentService(String name) {
super(name);
}
@Override
public void setIntentRedelivery(boolean enabled) {
super.setIntentRedelivery(enabled);
Log.d(TAG,"setIntentRedelivery:"+enabled+" ,"+Thread.currentThread());
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"onCreate"+" ,"+Thread.currentThread());
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG,"onStart"+" ,"+Thread.currentThread());
}
//这边的intent可以获取startService中传递进来的参数
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand:"+startId+" ,"+Thread.currentThread());
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy"+" ,"+Thread.currentThread());
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG,"onBind"+" ,"+Thread.currentThread());
return super.onBind(intent);
}
//这边的intent可以获取startService中传递进来的参数
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.d(TAG,"onHandleIntent"+" ,"+Thread.currentThread());
}
}
//启动intentService
Intent intent = new Intent(SecondActivity.this,MyIntentService.class);
intent.putExtra("parmas1","abcd");//..按需要携带参数
intent.putExtra("parmas2",true);
SecondActivity.this.startService(intent);
源码分析
onCreate函数
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
@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,并获取其中的looper创建ServiceHandler(继承自Handler),使得ServiceHandler可以在子线程中处理消息
onStartCommand函数
/**
* 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(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
对于onStartCommand只是简单的调用了onStart方法
onStart函数
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在onStart方法中,所做的处理便是将startService传递过来的Intent和启动startId包装在Message中传递给ServiceHandler进行处理
回调onHandleIntent处理消息
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中,便是回调执行用户重写的onHandleIntent方法,
执行完毕之后,注意调用的stopSelf(startId),Handler中我们处理完每一个命令都会调用stopSelf(int)方法来停止服务:该方法需要来自onStartCommand方法中的启动ID,只有传入的startId是onStartCommand方法中接收到的最新启动ID时才会停止服务,就是说,我们的IntentService直到命令队列中的所有命令被执行完后才会停止服务。
//会停止service并回调onDestroy
public final void stopSelf() {
stopSelf(-1);
}
//会判断传入的startId与当前startService所传入的startId是否一致,一致才停止Service并回调onDestroy,否则不停止,由此实现连续多次启动IntentService时,每次回调执行完onHandleIntent后,不会立即退出IntentService,而是接着执行Handler队列中的消息
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
onDestroy函数
@Override
public void onDestroy() {
mServiceLooper.quit();
}
退出消息队列
qrcode_for_gh_1bbc19ef669d_258.jpg
网友评论