文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处以及作者@恺风Wei。
何为IntentService
在进一步学习如何进行长时间运行的broadcast receiver之前,我们需要学习一下IntentService。前面提到需要一个service,而执行代码运行在线程,Android提供的IntentService符合这个要求。详细使用可参考Android学习笔记(五一):服务Service(上)-IntentService。我们将从原理上了解IntentService。
IntentService是local service,是Service的继承类。当调用startService()时,IntentService会将请求放入到子线程的队列中,利用handler,确保依次运行在同一个子线程中,但队列中所有请求执行完,worker线程将结束。下面是一个例子:
public class MyService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
//在子线程的处理代码
… …
}
}
IntentService的源代码
public abstract class IntentService extends Service {
//volatile我们很少使用,可以尽可能在线程中同步变量最新的数据,例如在主线程修改了某个变量,最新值可以尽快地同步到线程中。不同线程有着不同的存贮空间,即工作线程内存和主线程内存空间不同,当工作线程写某个主线程的变量,将具体值copy到工作线程内容,修改后,再写回主线程的内存的变量,由此实现同步。使用volatile确保每次使用的是最新的数值。注意这不是原子操作,和synchronized不同,仍可能会产生读写的混乱。所以这个volatile真的很少啊。
//Looper类用来为一个线程开启一个消息循环。Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
//stopSelf():如果没有挂起的消息,将结束service。
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
@Override
public void onCreate() {
super.onCreate();
//在onCreate()中创建一个worker thread,而不是在onStartCommand(),这是保证有唯一的worker线程而不是多个工作线程。
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//为worker线程创建一个looper用来处理消息,通过消息队列使之可以依次处理多个消息,无需重新开启新的工作线程。
mServiceLooper = thread.getLooper();
//建立一个handler,可以通过该handler将消息加入线程的消息队列中,并进行消息处理。
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override//发送消息(将消息加入到队列中)
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
protected abstract void onHandleIntent(Intent intent);
}
相关链接:我的Android开发相关文章