需求:有时需要从主线程往工作线程发送消息,在工作线程中处理消息。
原理:
HandlerThread类
HandlerThread提供一个getLooper的方法,返回一个looper对象。创建handler实例,handler=new Handler(looper),这样handler就与此looper对象关联起来,然后looper轮询工作线程的MessageQueue,处理消息。
IntentService类
我们知道启动service的时候是StartService(intent),会将本次启动的一个intent对象传过来,结合HandlerThread的特点,可以设计在工作线程也就是HandlerThread实例中处理intent。结合下面的IntentService简化代码实例,我们发现onStartCommand方法在各种业务中几乎都是一样的,onDestroy方法也是固定模式,onCreate方法中也只有接到消息内容intent的时候处理方法不一样,所以把这个处理intent的方法剥离出来,其他部分代码固定下来,就形成了Intentservice类,其子类只需要实现剥离处理的那个抽象类实现处理方法即可。
总的来说就是,将HandlerThread与IntentService结合起来使用,可以从主线程多次启动intentservice并传送intent,启动后IntentService会创建一个HandlerThread线程实例,将handler和HandlerThread关联,handler将intent包装消息发出去,然后handler处理消息,处理完毕停止本次启动。
启动模式的Service的三个主要方法:
public void onCreate() {}
public int onStartCommand(Intent intent, int flags, int startId) {}
public void onDestroy() {}
应用:比如应用于为音乐下载提供服务,每点击下载音乐一次,就会将上述的过程执行一遍。
HandlerThread简化代码实例:
public class MyHandlerThread extends Thread {
private Looper looper;
public Looper getLooper(){
if(!isAlive())
looper=null;
if(looper==null){
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return looper;
}
@Override
public void run() {
//创建消息队列
Looper.prepare();
//获取looper对象
looper=Looper.myLooper();
synchronized (this) {
this.notify();
}
//开始轮询
Looper.loop();
}
public void quit(){
if(looper!=null){
looper.quit();
}
}
public abstract class MyIntentService extends Service {
private HandlerThread thread;
private Handler handler;
@Override
public void onCreate() {
thread=new HandlerThread("workthread");
thread.start();
Looper looper=thread.getLooper();
handler=new Handler(looper){
@Override
public void handleMessage(Message msg) {
//处理异步任务
handlerIntent((Intent)msg.obj);
//停止本次启动
stopSelf(msg.arg1);
}
};
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg=Message.obtain();
msg.arg1=startId;
msg.obj=intent;
handler.sendMessage(msg);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
thread.quit();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public abstract void handlerIntent(Intent intent) ;