相关文章
Android消息队列机制
IntentService中的耗时操作
由于Service和Broadcast都是运行在主线程中,所以在这两个里面我们无法做一些长时间的耗时操作,要执行耗时操作可以用异步线程AsyncTask或者IntentServie。IntentServie的好处是调用玩后会自己关闭service。
用法
调用基本是重写IntentService,然后生成intent,startService。
public class MyIntentService extends IntentService {
//必须创建构造方法
//因为IntentService里面已经有个一个构造方法了,构建的时候jvm不会再构造一个构造方法了。
//你继承IntentService如果不添加构造方法将没有构造方法。jvm会报错。
//java.lang.InstantiationException: java.lang.Class<***.MyService> has no zero argument constructor
public MyIntentService () {
super("");
}
//实现你要做的内容
@Override
protected void onHandleIntent(@Nullable Intent intent) {
System.out.println("工作线程是: "+Thread.currentThread().getName());
String task = intent.getStringExtra("task");
System.out.println("任务是 :"+task);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//在Manifest.xml中注册服务
//调用方式。
Intent intent = new Intent(this,MyIntentService .class);
intent.putExtra("task","播放音乐");
startService(intent);
原理
IntentService里面可以执行耗时操作,下面看下它是怎么实现的。
package android.app;
import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
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);
}
}
public IntentService(String name) {
super();
mName = name;
}
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(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
/**
* 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;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
IntentService 继承Service 。它里面主要是开了一个HandlerThread,执行耗时的操作的内容就在工作线程里面操作。
在onCreate的时候执时候,新建了一个HandlerThread
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();
//建立线程的Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
HandlerThread继承了Thread,实现的run方法是建立一套安卓的异步消息队列的。
//HandlerThread的run方法。
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
在工作的时候,HandlerThread的onStart放就新建一个message放到handler里面。
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
Handler是另外定义的,对应到内部类是ServiceHandler 。
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);
}
}
这里可以看出,执行handleMessage时候先执行onHandleIntent((Intent)msg.obj);
,然后在执行stopSelf(msg.arg1);
onHandleIntent是你自己定义的要执行的内容,stopSelf是结束service。也是就是说,执行完耗时操作后,会关掉service。
//Service 里面的
/**
* Stop the service, if it was previously started. This is the same as
* calling {@link android.content.Context#stopService} for this particular service.
*
* @see #stopSelfResult(int)
*/
public final void stopSelf() {
stopSelf(-1);
}
/**
* Old version of {@link #stopSelfResult} that doesn't return a result.
*
* @see #stopSelfResult
*/
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}