美文网首页
Android 线程间通信

Android 线程间通信

作者: gzfgeh | 来源:发表于2017-03-27 22:54 被阅读40次
    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的身影!!!

    相关文章

      网友评论

          本文标题:Android 线程间通信

          本文链接:https://www.haomeiwen.com/subject/xoldottx.html