在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); ...