在Android线程池里运行代码任务实例
本节展示如何在线程池里执行任务。流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行。
本课同时向你展示了如何停止正在运行的任务。
在线程池里的线程上执行任务
在ThreadPoolExecutor.execute()里传入Runnable对象启动任务。这个方法会把任务添加到线程池工作队列。当有空闲线程时,管理器会取出等待最久的任务,在线程上运行。
publicclassPhotoManager{
publicvoidhandleState(PhotoTaskphotoTask,intstate){
switch(state){
//Thetaskfinisheddownloadingtheimage
caseDOWNLOAD_COMPLETE:
//Decodestheimage
mDecodeThreadPool.execute(
photoTask.getPhotoDecodeRunnable());
...
}
...
}
...
}
当ThreadPoolExecutor启动Runnable时,会自动调用run()方法。
中断正在运行的代码
要停止任务,你需要中断任务的进程。你需要在创建任务的时候,保存一个当前线程的handle.
如:
classPhotoDecodeRunnableimplementsRunnable{
//Definesthecodetorunforthistask
publicvoidrun(){
/*
*StoresthecurrentThreadinthe
*objectthatcontainsPhotoDecodeRunnable
*/
mPhotoTask.setImageDecodeThread(Thread.currentThread());
...
}
...
}
要中断线程,调用Thread.interrupt()就可以了。提示:线程对象是系统控制的,可以在你的app进程外被编辑。因为这个原因,你需要在中断它前加访问锁,放到一个同步块里:
publicclassPhotoManager{
publicstaticvoidcancelAll(){
/*
*CreatesanarrayofRunnablesthat'sthesamesizeasthe
*threadpoolworkqueue
*/
Runnable[]runnableArray=newRunnable[mDecodeWorkQueue.size()];
//PopulatesthearraywiththeRunnablesinthequeue
mDecodeWorkQueue.toArray(runnableArray);
//Storesthearraylengthinordertoiterateoverthearray
intlen=runnableArray.length;
/*
*IteratesoverthearrayofRunnablesandinterruptseachone'sThread.
*/
synchronized(sInstance){
//Iteratesoverthearrayoftasks
for(intrunnableIndex=0;runnableIndex<len;runnableIndex++){
//Getsthecurrentthread
Threadthread=runnableArray[taskArrayIndex].mThread;
//iftheThreadexists,postaninterrupttoit
if(null!=thread){
thread.interrupt();
}
}
}
}
...
}
在大多数案例里,Thread.interrupt()会马上停止线程。可是,它只会停止在等待的线程,但不会中断cpu或network-intensive任务。为了避免系统变慢,你应该在开始尝试操作前测试等待中断的请求。
/*
*Beforecontinuing,checkstoseethattheThreadhasn't
*beeninterrupted
*/
if(Thread.interrupted()){
return;
}
...
//DecodesabytearrayintoaBitmap(CPU-intensive)
BitmapFactory.decodeByteArray(
imageBuffer,0,imageBuffer.length,bitmapOptions);
...