Android中异步处理技术

Android应用中各种类型的线程本质上都基于Linux系统的pthreads,在应用层可以分为三种类型的线程
1.主线程:又叫UI线程,此线程非线程安全,所以在应用更新UI的时候需要使用Handler发送消息到主线程更新。

2.Binder线程:解决进程与进程之间的通信问题。每个进程都维护了一个线程池,用来处理其它进程中线程发送的消息。一个比较典型的使用场景是应用提供一个给其它进程通过AIDL接口绑定的Service。

3.后台线程:在应用中显式创建的线程都是后台线程,也就是说需要手动添加任务的线程,在Linux系统层面UI线程和后台线程其实是一样的。在Android框架中,通过WindowManager赋予了主线程只能处理UI更新以及后台线程不能直接操作UI的限制。

主要实现方式有以下几种
1.Thread Runnable java 中的线程机制
2.HandlerThread 是集成了Looper和MessageQueue源码如下

public void run(){
...
looper.prepare();
synchronized(this){
    mLooper = Looper.myLooper();
    notifyAll();
}
looper.loop();
}

looper.prepare() 生成了一个looper对象,mLooper = Looper.myLooper() 获取到刚刚生成的looper对象使用。使用方法如下

HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper()){
  @Override
  public void handleMessage(Message msg)[
      super.handleMessage(msg)
  }
}

handlerThread.getLooper() 是阻塞的只有当HandlerThread start()后才回继续执行,否则一直阻塞。所以要先开启再调用。

public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

3.IntentService
Service 的各个生命周期函数都是运行在主线程的,因此它本身并不是一个一步处理技术,为了能够在Service中实现子线程中处理耗时任务,Android引入了一个Service的子类:IntentService。IntentService具有和Service一样的生命周期,同时也提供了在后台线程中处理异步任务的机制。IntentService 也是在后台线程中执行所有的任务,我们通过给Context.startService传递一个Intent类型的参数可以启动IntentService,如果此时有任务正在执行,则这个Intent将会进入队列进行排队,如果没有任务,那么将会启动一个新的IntentService,当所有任务结束完成之后,IntentService将会自动结束它的生命周期。

4.AsyncTask
部分源码如下

private static abstract class WorkerRunnable implements Callable {
        Params[] mParams;
    }

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

        mFuture = new FutureTask(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(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) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }

  public final AsyncTask 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;
    }

可以看出它的内部实现了一个Callable的接口。然后放入FutureTask中,并
监听它的done()方法,一旦外部调用execute()方法,这个FutureTask对象就被放入线程池当中。等待执行完毕,done()会被回调,并通过Handler发送消息给主线程来更新UI。

5.Loader Android3.0 引入的异步数据加载框架,其实就是对AsyncTask进行了MVP设计模式的封装,使得异步数据加载更加容易实现和维护,结构更加清晰。如果大家有兴趣可以去看源码或者看这篇博客,讲的已经挺清楚的了。
http://www.jianshu.com/p/385327e35711

你可能感兴趣的:(Android中异步处理技术)