简单描述一下Service
Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念。
那么这里面要强调的是Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR,为了解决这样的问题,引入了IntentService
简单描述一下IntentService
IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期。那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务。IntentService使用队列的方式将请求的Intent加入队列,然后开启了一个Worker Thread(工作线程)在处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后在处理第二个,每一个请求都会在一个单独的Worker Thread中处理,不会阻塞应用程序的主线程。
使用IntentService 必须首先继承IntentService并实现onHandleIntent()方法,将耗时的任务放在这个方法执行,其他方面,IntentService和Service一样。
IntentService有以下特点:
(1) 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
(2) 创建了一个工作队列,来逐个发送intent给onHandleIntent()。
(3) 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
(4) 默认实现的onBind()返回null
(5) 默认实现的onStartCommand()的目的是将intent插入到工作队列中
Service中提供了一个方法:
public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
这个方法的具体含义是,当你的需要这个service启动的时候,或者调用这个servcie的时候,那么这个方法首先是要被回调的。
同时IntentService中提供了这么一个方法:
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
这是一个抽象方法,也就是说具体的实现需要被延伸到子类。
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在这里我们可以清楚的看到其实IntentService在执行onCreate的方法的时候,其实开了一个线程HandlerThread,并获得了当前线程队列管理的looper,并且在onStart的时候,把消息置入了消息队列.
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);
}
}
在消息被handler接受并且回调的时候,执行了onHandlerIntent方法,该方法的实现是子类去做的。
结论:
IntentService是通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。
public class MyIntentService extends IntentService {
String TAG = "MyIntentService";
public MyIntentService() {
super("luwenje");
}
@Override
protected void
onHandleIntent(Intent intent) {
Log.d(TAG, "-->开始睡眠");
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "-->睡眠结束");
}
public static void startMyIntentService(Context mContext) {
Intent intent = new Intent(mContext, MyIntentService.class);
mContext.startService(intent);
}
}
public class MyService extends Service {
String TAG = "MyService";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "-->开始睡眠");
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "-->睡眠结束");
return super.onStartCommand(intent, flags, startId);
}
public static void startMyService(Context mContext) {
Intent intent = new Intent(mContext, MyService.class);
mContext.startService(intent);
}
}
Android中IntentService有何优点
IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。
这是一个基于消息的服务,每次启动该服务并不是马上处理你的工作,而是首先会创建对应的Looper,Handler并且在MessageQueue中添加的附带客户Intent的Message对象,当Looper发现有Message的时候接着得到Intent对象通过在onHandleIntent((Intent)msg.obj)中调用你的处理程序.处理完后即会停止自己的服务.意思是Intent的生命周期跟你的处理的任务是一致的.所以这个类用下载任务中非常好,下载任务结束后服务自身就会结束退出