Android 线程间通信

2017-03-27  本文已影响40人  gzfgeh
Android系统为多线程提供的几种方案以及各自应用场景

1、异步任务 AsyncTask
AsyncTask是切换UI线程和工作线程的一种快捷方式,默认是一种线性队列执行方式。
场景:是那种需要立即执行的、生命周期短的需求
比如:界面上面有一个Button,点击立即从后台获取信息这种需求.
缺点:不易使用和内存泄露

doInBackground(...){
  if (isCancelled)
            ...
}

需要在代码里面加判断来取消异步任务。
还有一个令很多人头疼的内存泄露问题,因为一般AsyncTask都是Activity/Fragment的内部类,很容易导致AsyncTask和Activity生命周期不一致导致内存泄露。
2、HandlerThread
HandlerThread是Looper+MessageQueue+Handler组合的一个简单实现。
场景:需要执行长时间任务的需求
比如:打开手机相机预览图片需求,如果用AsyncTask不能把后台拿到的结果快速反应到UI上,HandlerThread可以通过runOnUIThread方法快速把拿到的图片反应到UI上。再比如可以用这个开发一个网络图片加载库等等。
3、ThreadPool线程池
ThreadPool是并发处理的有效方案,把任务分成小任务,然后分发到各个不同的线程上面。
场景:大量、并发的请求任务
比如:网络请求库,图片加载库等大量并发请求的场景,Glide底层网络请求就是用的线程池

Glide createGlide() {
        if (sourceService == null) {
            final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
            //初始化线程池
            sourceService = new FifoPriorityThreadPoolExecutor(cores);
        }
    ......
}

缺点:消耗大量的CPU,因为每开一个线程耗费64K的内存,使用不当就会导致性能严重下降。
4、IntentService
IntentService是Service+HandlerThread,因为Service是执行在UI线程的,如果要在Service执行耗时任务也是需要开启线程执行的,这里android为我们提供了一个方便的方式就是Intentservice。
-----------------------------------------分割线--------------------------------------------
Handler:面试中大量问到了Handler、Looper、MessageQueue,以前不明白直到现在看了各个库的源码发现,底层都是用他们的机制实现的!
RxJava:

static class HandlerWorker extends Worker {
        private final Handler handler;
        private final RxAndroidSchedulersHook hook;
        private volatile boolean unsubscribed;

        HandlerWorker(Handler handler) {
            this.handler = handler;
            this.hook = RxAndroidPlugins.getInstance().getSchedulersHook();
        }

        @Override
        public void unsubscribe() {
            unsubscribed = true;
            handler.removeCallbacksAndMessages(this /* token */);
        }

        @Override
        public boolean isUnsubscribed() {
            return unsubscribed;
        }

        @Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (unsubscribed) {
                return Subscriptions.unsubscribed();
            }

            action = hook.onSchedule(action);

            ScheduledAction scheduledAction = new ScheduledAction(action, handler);

            Message message = Message.obtain(handler, scheduledAction);
            message.obj = this; // Used as token for unsubscription operation.

            handler.sendMessageDelayed(message, unit.toMillis(delayTime));

            if (unsubscribed) {
                handler.removeCallbacks(scheduledAction);
                return Subscriptions.unsubscribed();
            }

            return scheduledAction;
        }

        @Override
        public Subscription schedule(final Action0 action) {
            return schedule(action, 0, TimeUnit.MILLISECONDS);
        }
    }

Retrofit:

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

多多少少都能看到Handler的身影!!!

上一篇下一篇

猜你喜欢

热点阅读