你的位置:首页 > 操作系统

[操作系统]android线程与线程池


线程在android是个重要的概念,从用途上讲,线程分为主线程和子线程,主线程负责页面相关,子线程负责耗时操作。

在android中除了Thread本身还有 AsyncTask  IntentService  HandlerThread。

AsyncTask

  public abstract class AsyncTask<Params, Progress, Result> 

1 Params 参数类型
2 Progress 执行进度类型
3 Result 返回数据类型

不需要参数可以用Void代替

它提供了4个核心方法:

  //异步任务执行之前调用,一般用来执行一些准备操作       @Override       protected void onPreExecute() {         super.onPreExecute();       }       //在线程池调用, 用于执行异步任务       @Override       protected String doInBackground(String... params) {         return null;       }       //异步任务执行之后会调用       @Override       protected void onPostExecute(String result) {         super.onPostExecute(result);       }       //主线程中执行,后台任务执行进度发生改变调用       @Override       protected void onProgressUpdate(Void... values) {         super.onProgressUpdate(values);     } 

    

注意:

1 AsyncTask类必须在主线程中加载

2 AsyncTask的对象必须在主线程创建

3 execute必须在UI线程调用

4 一个AsyncTask的对象只能执行一次,即只调用一次execute方法


工作原理:

  public final AsyncTask<Params, Progress, Result> execute(Params... params) {       return executeOnExecutor(sDefaultExecutor, params);     }   execute 方法会调用 executeOnExecutor 方法;看一下 executeOnExecutor 方法:    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,         Params... params) {       if (mStatus != Status.PENDING) {         switch (mStatus) {           case RUNNING:             throw new IllegalStateException("Cannot execute task:"                 + " the task is already running.");           case FINISHED:             throw new IllegalStateException("Cannot execute task:"                 + " the task has already been executed "                 + "(a task can be executed only once)");         }       }          mStatus = Status.RUNNING;          onPreExecute();          mWorker.mParams = params;       exec.execute(mFuture);          return this;     } 

可以看出封装了一个线程池,接着找我发现了

  private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;   public static final Executor SERIAL_EXECUTOR = new SerialExecutor();      private static class SerialExecutor implements Executor {       final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();       Runnable mActive;          public synchronized void execute(final Runnable r) {         mTasks.offer(new Runnable() {           public void run() {             try {               r.run();             } finally {               scheduleNext();             }           }         });         if (mActive == null) {           scheduleNext();         }       } 

从SerialExecutor 看出AsyncTask是排队执行的过程。

系统首先会把AsyncTask的参数Params 封装为FutureTask对象,接着会把FutureTask交给SerialExecutor的execute处理,
execute方法把FutureTask交给mTasks任务队列中,如果这时没有AsyncTask任务,SerialExecutor会scheduleNext()来执行下一个任务。当一个任务执行完以后,SerialExecutor才会执行其他任务,可以看出AsyncTask是串行的。


AsyncTask构造函数有这样一段代码:

  mWorker = new WorkerRunnable<Params, Result>() {         public Result call() throws Exception {           mTaskInvoked.set(true);              Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);           //noinspection unchecked           return postResult(doInBackground(mParams));         }       }; 

再看FutureTask的run方法:

派生到我的代码片  public void run() {       if (state != NEW ||         !UNSAFE.compareAndSwapObject(this, runnerOffset,                        null, Thread.currentThread()))         return;       try {         Callable<V> c = callable;         if (c != null && state == NEW) {           V result;           boolean ran;           try {             result = c.call();             ran = true;           } catch (Throwable ex) {             result = null;             ran = false;             setException(ex);           }           if (ran)             set(result);         }       } finally {         // runner must be non-null until state is settled to         // prevent concurrent calls to run()         runner = null;         // state must be re-read after nulling runner to prevent         // leaked interrupts         int s = state;         if (s >= INTERRUPTING)           handlePossibleCancellationInterrupt(s);       }     } 

发现FutureTask的run方法是执行了mWorker的call的,所以call也会在线程池中执行。


mWorker的call中将mTaskInvoked.set(true);表示当前任务已经调用然后执行AsyncTask的doInBackground方法接着将
返回值传给postResult方法;

  private Result postResult(Result result) {      @SuppressWarnings("unchecked")      Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,          new AsyncTaskResult<Result>(this, result));      message.sendToTarget();      return result;    } 

可以看出postResult通过一个Handler发送一个MESSAGE_POST_RESULT消息

  private static Handler getHandler() {       synchronized (AsyncTask.class) {         if (sHandler == null) {           sHandler = new InternalHandler();         }         return sHandler;       }     }           private static class InternalHandler extends Handler {       public InternalHandler() {         super(Looper.getMainLooper());       }          @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})       @Override       public void handleMessage(Message msg) {         AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;         switch (msg.what) {           case MESSAGE_POST_RESULT:             // There is only one result             result.mTask.finish(result.mData[0]);             break;           case MESSAGE_POST_PROGRESS:             result.mTask.onProgressUpdate(result.mData);             break;         }       }     } 

当这个Handler收到MESSAGE_POST_RESULT消息之后,会调用finish方法了

  private void finish(Result result) {       if (isCancelled()) {         onCancelled(result);       } else {         onPostExecute(result);       }       mStatus = Status.FINISHED;     } 

如果取消执行就 onCancelled 了,否则就调用onPostExecute这个方法。