IntentService源码实例讲解
来源:互联网 发布:office2007办公软件 编辑:程序博客网 时间:2024/06/18 14:22
service的基本使用基本大家都学习过, 也大概用过,
比如startService(), stopService(), bindService, unbindService();
比如调用startService的Activity一旦销毁, 那么Service可能处于不可管控状态;
又比如Service中要想做一些耗时任务, 必须要自己启动线程, 或者还得要使用线程池。
那么是不是可以有这么一个东西, 它既可以有service的一些优点, 对service的缺点也做出了优化呢?
YES, IntentService就做到了, 它的内部使用了HandlerThread同时配合handler来
实现了在service中可以做耗时操作;
相应的task完成之后, service也做到了自动终结, 无须开发者手动终止service.
下面来看看IntentService的源码吧:
public abstract class IntentService extends Service {首先它是继承自Service, 同时还是个抽象类, 估摸着在用它的时候是不是还得重写它的方法?①
(1)从Service的角度来看,无论咋样,应该都是有onCreate(), onStartCommand(), onBind(), onDestroy()这些方法的,
那么先来看看onCreate()吧:
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);}
其中创建了HandlerThread(Thread,Loop结合体),并通过thread的Looper创建了Handler,
也就是说在onCreate()中,创建了子线程,同时基于子线程创建了Handler处理消息;
(2)看看onStartCommand()方法吧
public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}
其中调用了onStart(intent, startId)方法;
public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg);}
在其中创建了Message,并将intent,startId作为msg的成员;将该Message发给Handler处理;
具体看看Handler怎么处理吧:
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); }}第一步:调用onHandleIntent方法处理该Message消息;
第二步:调用stopSelf(msg.arg1),在消息队列中没有消息的时候,结束当前service
好,先从onHandleIntent((Intent)msg.obj)看起,发现这个是个抽象函数,那么这个
就应该是本文开头所说的继承IntentService所需要重写的方法了。
由于IntentService的onCreate()方法里面创建了子线程,子线程内部又创建了Handler,
那么onHandleIntent方法中自然就可以做一些耗时操作了。
那么再所说stopSelf(msg.arg1),在原先Service中,我们需要停掉startService启动
的Service的话,需要调用stopService()或者stopSelf(),
其实stopSelf() 内部也是调用stopSelf(int startId),只不过传入的参数为-1罢了。
public final void stopSelf(int startId) { if (mActivityManager == null) { return; } try { mActivityManager.stopServiceToken( new ComponentName(this, mClassName), mToken, startId); } catch (RemoteException ex) { }}
内部具体调用,如果handler内部消息队列中没有消息需要处理,就终止Service,
如果其中还有消息需要处理,则让Handler处理消息,消息都处理完在终止该Service.
对于Framework不了解的同学,后面我会在案例中进行验证:②
(3)再来说说onBind(),这里重写了Service的onBind()并直接返回null
那么就可以看出,IntentService在设计之初就不考虑支持bindService,unbindService()的,
另外bindService的调用流程,也不会走onStartCommand()方法,这与IntentService设计理念不吻合,
所以如果在IntentService中重写onBind(),并通过bindService来绑定服务的话,那么IntentService与
普通Service是没有区别的,也体现不出IntentService的优势。
(4)最后说下onDestroy()
其中只有一行代码:mServiceLooper.quit();
即将onCreate()中HandlerThread中的loop循环停止,即handler停止工作,onCreate()中
创建的HandlerThread停止工作,整个Service终止。
(5)对几处疑问点做实例说明:
先附上Service部分的代码:
package intentservice.cn.example.com.intentservicetest;import android.app.IntentService;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class MyIntentService extends IntentService { public static final String TAG = "MyIntentService";
//在注册Service的时候会提醒添加默认构造函数,否则运行崩溃,我也是实际运行时才发现
public MyIntentService() { super("MyIntentService"); }public MyIntentService(String name) {
super(name);
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId); }
@Override
public void onStart(Intent intent, int startId) {
Log.d(TAG, "onStart,send msg to handler");
super.onStart(intent, startId);
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent invoked by handler. begin.");
//模拟耗时任务
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "onHandleIntent invoked by handler. end.");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return super.onBind(intent);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
}
①连续多次StartService的时候,IntentService的生命周期流程:
Intent service = new Intent(this, MyIntentService.class);startService(service);startService(service);
11-26 06:34:13.584 D/MyIntentService( 2998): onCreate
11-26 06:34:13.589 D/MyIntentService( 2998): onStartCommand
11-26 06:34:13.589 D/MyIntentService( 2998): onStart,send msg to handler
11-26 06:34:13.590 D/MyIntentService( 2998): onStartCommand
11-26 06:34:13.590 D/MyIntentService( 2998): onStart,send msg to handler
11-26 06:34:13.591 D/MyIntentService( 2998): onHandleIntent invoked by handler. begin.
11-26 06:34:15.592 D/MyIntentService( 2998): onHandleIntent invoked by handler. end.
11-26 06:34:15.593 D/MyIntentService( 2998): onHandleIntent invoked by handler. begin.
11-26 06:34:17.594 D/MyIntentService( 2998): onHandleIntent invoked by handler. end.
11-26 06:34:17.596 D/MyIntentService( 2998): onDestroy
可见Service中是异步处理消息的,同时这种情况下onCreate()只执行一次,onStartCommand的次数跟startService次数一样。
另外,只有消息队列中所有msg都处理结束的时候,onDestroy()才会执行。
②第一次StartService中task完成后,过一段时间再次StartService,IntentService的生命周期流程:
final Intent service = new Intent(this, MyIntentService.class);startService(service);new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } startService(service); }}).start();
11-26 06:18:25.373 D/MyIntentService( 2998): onCreate
11-26 06:18:25.384 D/MyIntentService( 2998): onStartCommand
11-26 06:18:25.385 D/MyIntentService( 2998): onStart,send msg to handler
11-26 06:18:25.385 D/MyIntentService( 2998): onHandleIntent invoked by handler. begin.
11-26 06:18:27.387 D/MyIntentService( 2998): onHandleIntent invoked by handler. end.
11-26 06:18:27.389 D/MyIntentService( 2998): onDestroy
11-26 06:18:28.252 D/MyIntentService( 2998): onCreate
11-26 06:18:28.255 D/MyIntentService( 2998): onStartCommand
11-26 06:18:28.256 D/MyIntentService( 2998): onStart,send msg to handler
11-26 06:18:28.257 D/MyIntentService( 2998): onHandleIntent invoked by handler. begin.
11-26 06:18:30.258 D/MyIntentService( 2998): onHandleIntent invoked by handler. end.
11-26 06:18:30.260 D/MyIntentService( 2998): onDestroy
很明显,第二次startService的开始时间是在第一次startService中的task完成之后,
所以第一次startService中的task完成之后,发现队列中并没有其他msg需要处理,所以直接调用onDestroy()了。
这种情况下,service生命周期都会重新执行,包括其中handler,thread等。
实验过程中:别忘了注册Service哈!!
好了,IntentService算是讲完了,大家都基本理解了没,欢迎提问交流。
- IntentService源码实例讲解
- 一个IntentService使用实例
- IntentService源码解说
- IntentService源码分析
- IntentService源码详解
- IntentService源码分析
- IntentService源码分析
- IntentService源码分析
- IntentService源码解析
- IntentService 源码解析
- IntentService源码分析
- Android IntentService源码解读
- Android IntentService 源码解析
- IntentService源码解读
- IntentService源码分析
- IntentService从源码解析
- 从源码分析IntentService
- IntentService源码分析
- 学习ubuntu 下git 使用(一)
- Batch Normalization导读
- 7-3 是否完全二叉搜索树
- shell学习二十四--while循环
- Python Exception处理
- IntentService源码实例讲解
- 11.26_周总结
- LeetCode 198. House Robber (Easy)
- JavaScript 16 字符串
- 基于dokcer实现自动化集成和无状态持续交付
- soa与java中间件的关系?
- 看看清华人是如何学习和生活的
- SVM——(七)SMO(序列最小最优算法)
- Kruskal 算法 java