关于android Service 跟线程 总结几点
1: android 服务不是单一的进程。服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中。(app退出后服务任然可以运行)
2: android 的Service 一定运行在 主线程,即使在子线程开启一个服务,服务的onCreat(),onStart() 都会运行在主线程,所有别期望在服务中做耗时操作!!
3:服务的生命周期必须手动管理,丢弃不管它将一直运行除非系统资源紧缺将其回收
为何使用Service?,使用Service跟直接在Activity启动线程有和区别?
简单的说就是android 系统对线程回收的优先级的机制导致需要使用服务或者说服务的线程更不容易被系统回收!
如果一个任务的返回结果依赖于界面,如:界面刷新或者更新用户操作后的数据;这样的任务应该直接由界面开启线程去执行,界面结束了那这条线程也没有活着的必要了;
服务是执行相对较长时间的任务 如:
1:心跳检测或者其他机制的检查,需要伴随App整个生命周期的任务;
2:文件下载,可能是由某个界面触发的文件下载,但用户不可能一直在那界面等待,如果没有Service 当用户结束界面时,此界面所启动的线程很可能就被系统回收了!那么文件下载可能就被终止了,这可能不是用户想要的;(这里涉及到系统线程回收的优先级,暂不深入)
3:数据状态的更新与保存,在聊天界面中 可能用户发送了一条消息,由于网络延时,消息发送比较慢,用户返回了界面,这时候消息应该是能被继续发送的,而消息的发送结果又关系到消息界面(成功失败都要更新界面),这种情况消息发送应该是在服务里处理,成功后应该保存完数据后回调界面的接口通知界面去更新数据;
服务有这么多优点,但实际开发中却没那么多人喜欢用服务,原因可能就是服务的生命周期必须自己管理,稍有不慎都会引起crash,就比如下载文件,当我们启动服务下载文件后,下载完成后我们就必须手动的调用stopService();但是下载又是异步的,这样管理起来就麻烦了! 其实Google已经帮我们考虑了这种情况了,这时候就可以用IntentService;
IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去你执行你的耗时操作。
这里我 需要解释以下几个方法。
Service中提供了一个方法:
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
这个方法的具体含义是,当你的需要这个service启动的时候,或者调用这个servcie的时候,那么这个方法首先是要被回调的。
同时IntentService中提供了这么一个方法:
protected abstract void onHandleIntent(Intent intent);
这是一个抽象方法,也就是说具体的实现需要被延伸到子类。
上面提到过IntentService是继承Service的,那么这个子类也肯定继承service,那么onHandleIntent()方法是什么时候被调用的呢?让我们具体看IntentService的内部实现:
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);
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService(String name) {
super();
mName = name;
}
/**
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
*
* <p>If enabled is true,
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_REDELIVER_INTENT}, so if this process dies before
* {@link #onHandleIntent(Intent)} returns, the process will be restarted
* and the intent redelivered. If multiple Intents have been sent, only
* the most recent one is guaranteed to be redelivered.
*
* <p>If enabled is false (the default),
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
* dies along with it.
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@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);
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在这里我们可以清楚的看到其实IntentService在执行onCreate的方法的时候,其实开了一个线程HandlerThread,并获得了当前线程队列管理的looper,并且在onStart的时候,把消息置入了消息队列
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
在消息被handler接受并且回调的时候,执行了onHandlerIntent方法,该方法的实现是子类去做的。
结论:
IntentService是通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况,就是Service 里启动子线程 子线程完成时自动帮你关闭服务,不用手动管理服务的生命周期!