有空的可以先看看这篇,Android组件与进程,进程的优先级,组件都在主线程,线程安全等。
提到android的多线程,必须提下特有的异步task类,AsyncTask。
AsyncTask 的优势体现在:
线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。
代码更简洁,实现起来更方便。
AsyncTask的本质是一个线程池,所有提交的异步任务都会在这个线程池中的工作线程内执行,当工作线程需要跟UI线程交互时,工作线程会通过向在UI线程创建的Handler传递消息的方式,调用相关的回调函数,从而实现UI界面的更新。
成员变量:
private static final int CORE_POOL_SIZE = 5;//5个核心工作线程 private static final int MAXIMUM_POOL_SIZE = 128;//最多128 private static final int KEEP_ALIVE = 1;//空闲线程超时时间1s private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10);//等待队列 private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } };//线程工厂 private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);//自定义线程池 private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static final int MESSAGE_POST_CANCEL = 0x3; private static final InternalHandler sHandler = new InternalHandler();//内部的handler构造方法,注意这个初始化一定要在UI线程中进行:
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return doInBackground(mParams); } }; mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { Message message; Result result = null; try { result = get(); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { message = sHandler.obtainMessage(MESSAGE_POST_CANCEL, new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null)); message.sendToTarget();//取消任务 return; } catch (Throwable t) { throw new RuntimeException("An error occured while executing " + "doInBackground()", t); } message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result)); message.sendToTarget();//成功,发送message } }; }WorkerRunnable类实现了callable接口的call()方法,该函数会调用我们在AsyncTask子类中实现的doInBackground(mParams)方法,由此可见,WorkerRunnable封装了我们要执行的异步任务。FutureTask中的protected void done() {}方法实现了异步任务状态改变后的操作。当异步任务被取消,会向UI线程传递MESSAGE_POST_CANCEL消息,当任务成功执行,会向UI线程传递MESSAGE_POST_RESULT消息,并把执行结果传递到UI线程。
下面是AsyncTask的execute(Params...params)方法
public final AsyncTask<Params,Progress, Result> execute(Params... params) { if (mStatus != Status.PENDING) {//Status有PENDING(未执行),RUNNING(正在执行),FINISHED(已完成)三个状态,如果mStatus不为PENDING,则抛出异常 switch (mStatus) { case RUNNING: throw newIllegalStateException("Cannot execute task:" + " the taskis already running."); case FINISHED: throw newIllegalStateException("Cannot execute task:" + " the taskhas already been executed " + "(a task canbe executed only once)"); } } mStatus = Status.RUNNING; onPreExecute();//运行在ui线程,在提交任务到线程池之前执行 mWorker.mParams = params; sExecutor.execute(mFuture);//提交任务到线程池 return this; }
当任务的状态发生改变时(1、执行成功2、取消执行3、进度更新),工作线程会向UI线程的Handler传递消息。Handler要处理其他线程传递过来的消息。在AsyncTask中,InternalHandler是在UI线程上创建的,它接收来自工作线程的消息,实现代码如下:
private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked","RawUseOfParameterizedType"}) @Override public voidhandleMessage(Message msg) { AsyncTaskResult result =(AsyncTaskResult) msg.obj; switch (msg.what) { caseMESSAGE_POST_RESULT: // There is onlyone result result.mTask.finish(result.mData[0]);//执行任务成功 break; caseMESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData);//进度更新 break; caseMESSAGE_POST_CANCEL: result.mTask.onCancelled();//取消任务 break; } } }
3、当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数
4,AsyncTask在Activity因为OnConfiguration重绘时要注意。
参考:http://blog.csdn.net/mylzc/article/details/6774131