安卓中实现异步任务的几种方式
问题背景
在安卓日常开发中,经常需要使用到异步任务,现在把安卓中异步任务的几种主要使用方式简单总结一下,后面有需要会对他们每一种进行单独的细致介绍。
问题分析
(1)Thread(Runnable)结合handler实现
实现demo如下:
Handler mHandler = newHandler(){
    @Override
    publicvoid handleMessage(Message msg){
        if(msg.what == 1){
            textView.setText("Task Done!!");
        }
    }
};
mRunnable = new Runnable() {
    @Override
    publicvoid run() {
        // 模拟执行耗时操作
        SystemClock.sleep(1000);
        mHandler.sendEmptyMessage(1);  
    }
};
private void startTask(){
    // 启动子线程
    new Thread(mRunnable).start();
}
(2)结合AsyncTask实现
看下官方给的demo:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
}
实现AsyncTask的子类,主要实现其 doInBackground()、onProgressUpdate()、onPostExecute()方法。使用时创建对应对象调用即可。代码如下:
new DownloadFilesTask().execute(url1, url2, url3);
(3)基于HandlerThread实现
public class HandlerThreadTest {
    private final static String TAG = "HandlerThreadTest";
    private HandlerThread mHandlerThread = new HandlerThread("myHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
    private Handler mHandler = null;
    public void startHandlerthread(){
        mHandlerThread.start();
        if (mHandler == null){
            mHandler = new Handler(mHandlerThread.getLooper()){
                @Override
                public void handleMessage(@NonNull Message msg) {
                    super.handleMessage(msg);
                    switch (msg.what){
                        case 1:
                            Log.d(TAG, "收到消息,当前线程:" + Thread.currentThread());
                            break;
                    }
                }
            };
        }
    }
    public void sendMessage() {
        Log.d(TAG, "当前线程:" + Thread.currentThread());
        Message msg = Message.obtain();
        msg.what = 1;
        mHandler.sendMessage(msg);
    }
}
(4)IntentService的方式实现
我们来看下 IntentService 的主要方法:
    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }
我们只需要继承 IntentService,就可以在 onHandlerIntent 方法中异步处理 Intent 类型任务了。
(5)使用线程池来实现
利用 Executors 的静态方法 newCachedThreadPool()、newFixedThreadPool()、newSingleThreadExecutor() 及重载形式实例化 ExecutorService 接口即得到线程池对象。这个有机会后面会单独写篇文章介绍一下。
问题总结
本文大体介绍了安卓开发日常,经常使用到的几种实现异步任务的方案,后面有机会会对每一种单独进行细致的介绍。










