都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。

刚刚过去2019,新的一年2020年。都说衣不如新人不如故,技术是学新不学旧的?但是旧的知识不巩固,根基不固很容易在面试或者实战遇到很大的问题的java

如下知识点PDF版后续可见
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。android

更多面试内容等等
(更多完整项目下载。未完待续。源码。图文知识后续上传github。)
(VX:mm14525201314)
https://github.com/xiangjiana/Android-MSgit

一丶线程篇

一、线程池的好处? 四种线程池的使用场景,线程池的几个参数的理解?

参考答案
使用线程池的好处是减小在建立和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。若是不使用线程池,有可能形成系统建立大量同类线程而致使消耗完内存或则“过分切换”的问题,概括总结就是github

  • 重用存在的线程,减小对象建立、消亡的开销,性能佳。
  • 可有效控制最大并发线程数,提升系统资源的使用率,同时避免过多资源竞争,避免堵塞
  • 提供定时执行、按期执行、单线程、并发数控制等功能。

Android 中的线程池都是直接或间接经过配置
ThreadPoolExecutor 来实现不一样特性的线程池.Android 中最多见的类具备不一样特性的线程池分别为:面试

  • newCachedThreadPool 只有非核心线程,最大线程数很是大,全部线程都活动时会为新任务建立新线程,不然会利用空闲线程 ( 60s 空闲时间,过了就会被回收,因此线程池中有 0 个线程的可能 )来处理任务.
    优势: 任何任务都会被当即执行(任务队列SynchronousQuue 至关于一个空集合);比较适合执行大量的耗时较少的任务.算法

  • newFixedThreadPool 只有核心线程,而且数量固定的,全部线程都活动时,由于队列没有限制大小,新任务会等待执行,当线程池空闲时不会释放工做线程,还会占用必定的系统资源。
    优势: 更快的响应外界请求编程

  • newScheduledThreadPool 核心线程数固定,非核心线程(闲着没活干会被当即回收数)没有限制.
    优势: 执行定时任务以及有固定周期的重复任务缓存

  • newSingleThreadExecutor 只有一个核心线程,确保全部的任务都在同一线程中按序完成
    优势: 不须要处理线程同步的问题

经过源码能够了解到上面的四种线程池实际上仍是利用ThreadPoolExecutor 类实现的安全

//详细介绍课参考Executors.java类
  public static ExecutorService newCachedThreadpool () {
         return new ThreadPoolExecutor (0,Integer.MAX_VALUE
                                        60L,TimeUnit.SECONDS,
                                        new SynchronousQueue<Runnable>());
  }
  ThreadPoolExecutor(int corepoolSize,int maxmumpoolSize,
                     long keepAliveTime,TimeUnit unit,
                     Blockingqueue<Runnable>workqueue,RejectedExecutionHandler handler
二、Android 中还了解哪些方便线程切换的类?

参考回答:服务器

  • AsyncTask 底层封装了线程池和 Handler,便于执行后台任务以及在子线程中进行 UI 操做。
  • HandlerThread 一种具备消息循环的线程,其内部可以使用Handler。
  • IntentService 是一种异步、会自动中止的服务,内部采用HandlerThread
三、 AsyncTask 的原理

参考回答:

  • AsyncTask 中有两个线程池(SerialExecutor 和THREAD_POOL_EXECUTOR)和一个 Handler(InternalHandler),其中线程池 SerialExecutor 用于任务的排队,而线程池THREAD_POOL_EXECUTOR 用于真正地执行任务,InternalHandler 用于将执行环境从线程池切换到主线程。
  • 静态的 Handler 对象,为了可以将执行环境切换到主线程,这就要求 这个对象必须在主线程建立。因为静态成员会在加载类的时候进行初始化,所以这就变相要求 AsyncTask 的类必须在主线程中加载,不然同一个进程中的 AsyncTask 都将没法正常工做。
四、IntentService 有什么用 ?

IntentService 可用于执行后台耗时的任务,当任务执行完成后会自动中止,同时因为 IntentService 是服务的缘由,不一样于普通 Service,IntentService 可自动建立子线程来执行任务,这致使它的优先级比单纯的线程要高,不容易被系统杀死,因此IntentService 比较适合执行一些高优先级的后台任务。

五、直接在 Activity 中建立一个 thread 跟在 service 中建立一个 thread 之间的区别?

参考回答:

  • 在 Activity 中被建立: 该 Thread 的就是为这个 Activity 服务的,完成这个特定的 Activity 交代的任务,主动通知该 Activity一些消息和事件,Activity 销毁后,该 Thread 也没有存活的意义了
  • 在 Service 中被建立: 这是保证最长生命周期的 Thread 的惟一方式,只要整个 Service 不退出,Thread 就能够一直在后台执行,通常在 Service 的 onCreate()中建立,在 onDestroy()中销毁。因此,在 Service 中建立的 Thread,适合长期执行一些独立于 APP 的后台任务,比较常见的就是:在 Service 中保持与服务器端的长链接。
六、ThreadPoolExecutor 的工做策略 ?

参考回答: ThreadPoolExecutor 执行任务时会遵循以下规则

  • 若是线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。
  • 若是线程池中的线程数量已经达到或则超过核心线程的数量,那么任务会被插入任务队列中排队等待执行。
  • 若是在第 2 点没法将任务插入到任务队列中,这每每是因为任务队列已满,这个时候若是在线程数量未达到线程池规定的最大值,那么会马上启动一个非核心线程来执行任务。
  • 若是第 3 点中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor 会调用RejectedExecutionHandlerrejectedExecution 方法来通知调用者。
    七、Handler、Thread 和 HandlerThread 的差异?

    参考回答:

  • Handler: 在 android 中负责发送和处理消息,经过它能够实现其余支线线程与主线程之间的消息通信。
  • Thread: Java 进程中执行运算的最小单位,亦即执行处理机调度的基本单位。某一进程中一路单独运行的程序。
  • HandlerThread: 一个继承自 Thread 的类 HandlerThread,Android 中没有对 Java 中的 Thread 进行任何封装,而是提供了一个继承自 Thread 的类 HandlerThread 类,这个类对 Java的 Thread 作了不少便利的封装。HandlerThread 继承于Thread,因此它本质就是个 Thread。与普通 Thread 的差异就在于,它在内部直接实现了 Looper 的实现,这是 Handler 消息机制必不可少的。有了本身的 looper,可让咱们在本身的线程中分发和处理消息。若是不用 HandlerThread 的话,须要手动去调用 Looper.prepare()Looper.loop()这些方法。
八、ThreadLocal 的原理

参考回答:
ThreadLocal 是一个关于建立线程局部变量的类。使用场景以下所示:

  • 实现单个线程单例以及单个线程上下文信息存储,好比交易 id 等
  • 实现线程安全,非线程安全的对象使用 ThreadLocal 以后就会变得线程安全,由于每一个线程都会有一个对应的实例。 承载一些线程相关的数据,避免在方法中来回传递参数。

当须要使用多线程时,有个变量恰巧不须要共享,此时就没必要使用 synchronized 这么麻烦的关键字来锁住,每一个线程都至关于在堆内存中开辟一个空间,线程中带有对共享变量的缓冲区,经过缓冲区将堆内存中的共享变量进行读取和操做,ThreadLocal 至关于线程内的内存,一个局部变量。每次能够对线程自身的数据读取和操做,并不须要经过缓冲区与 主内存中的变量进行交互。并不会像 synchronized 那样修改主内存的数据,再将主内存的数据复制到线程内的工做内存。ThreadLocal 可让线程独占资源,存储于线程内部,避免线程堵塞形成 CPU 吞吐降低。

在每一个 Thread 中包含一个 ThreadLocalMapThreadLocalMap 的 key 是 ThreadLocal 的对象,value 是独享数据。

九、多线程是否必定会高效(优缺点)

参考回答:
多线程的优势:

  • 方便高效的内存共享 - 多进程下内存共享比较不便,且会抵消掉多进程编程的好处
  • 较轻的上下文切换开销 - 不用切换地址空间,不用更改CR3 寄存器,不清空 TLB
  • 线程上的任务执行完后自动销毁

多线程的缺点:

  • 开启线程须要占用必定的内存空间(默认状况下,每个线程都占 512KB)
  • 若是开启大量的线程,会占用大量的内存空间,下降程序的性能
  • 线程越多,cpu 在调用线程上的开销就越大
  • 程序设计更加复杂,好比线程间的通讯、多线程的数据共享

综上得出,多线程不必定能提升效率,在内存空间紧张的状况下反而是一种负担,所以在平常开发中,应尽可能

  • 不要频繁建立,销毁线程,使用线程池
  • 减小线程间同步和通讯(最为关键)
  • 避免须要频繁共享写的数据
  • 合理安排共享数据结构,避免伪共享(false sharing)
  • 使用非阻塞数据结构/算法
  • 避免可能产生可伸缩性问题的系统调用(好比 mmap)
  • 避免产生大量缺页异常,尽可能使用 Huge Page
  • 能够的话使用用户态轻量级线程代替内核线程
十、多线程中,让你作一个单例,你会怎么作

参考回答:

  • 多线程中创建单例模式考虑的因素有不少,好比线程安全 -延迟加载-代码安全:如防止序列化***,防止反射***(防止反射进行私有方法调用) -性能因素
  • 实现方法有多种,饿汉,懒汉(线程安全,线程非安全),双重检查(DCL),内部类,以及枚举

    //OkHttp例子
    private static volatile OkHttpHelper SInstance;
    
    public static OkHttpHelper getInstance() {
         if (sInstance =null) {
             synchronized (OkHttpHelper.class) {
                if (sInstance =null) {
                    sInstance = new OkHttpHelper();
                }
             }
          }
     return sInstance;
    }
    十一、除了 notify 还有什么方式能够唤醒线程

    参考回答:

  • 当一个拥有 Object 锁的线程调用 wait()方法时,就会使当前线程加入 object.wait 等待队列中,而且释放当前占用的 Object锁,这样其余线程就有机会获取这个 Object 锁,得到 Object锁的线程调用 notify()方法,就能在 Object.wait 等待队列中随机唤醒一个线程(该唤醒是随机的与加入的顺序无关,优先级高的被唤醒几率会高)
  • 若是调用 notifyAll()方法就唤醒所有的线程。注意:调用notify()方法后并不会当即释放 object 锁,会等待该线程执行完毕后释放 Object 锁。
十二、什么是 ANR ? 什么状况会出现 ANR ?如何避免 ? 在不看代码的状况下如何快速定位出现 ANR 问题所在 ?

参考回答:

  • ANR(Application Not Responding,应用无响应):当操做在一段时间内系统没法处理时,会在系统层面会弹出 ANR 对话框
  • 产生 ANR 多是由于 5s 内无响应用户输入事件、10s 内未结束BroadcastReceiver、20s 内未结束 Service
  • 想要避免 ANR 就不要在主线程作耗时操做,而是经过开子线程,方法好比继承 Thread 或实现 Runnable 接口、使用AsyncTask IntentServiceHandlerThread

二丶Handler篇

一、谈谈消息机制 Handler 做用 ?有哪些要素 ?流程是怎样的 ?

参考回答:
负责跨线程通讯,这是由于在主线程不能作耗时操做,而子线程不能更新 UI,因此当子线程中进行耗时操做后须要更新 UI时,经过 Handler 将有关 UI 的操做切换到主线程中执行。

具体分为四大要素

  • Message(消息): 须要被传递的消息,消息分为硬件产生的消息(如按钮、触摸)和软件生成的消息。
  • MessageQueue(消息队列): 负责消息的存储与管理,负责管理由 Handler 发送过来的 Message。读取会自动删除消息,单链表维护,插入和删除上有优点。在其 next()方法中会无限循环,不断判断是否有消息,有就返回这条消息并移除。
  • Handler(消息处理器): 负责 Message 的发送及处理。主要向消息池发送各类消息事件(Handler.sendMessage())和处理相应消息事件(Handler.handleMessage()),按照先进先出执行,内部使用的是单链表的结构。
  • Looper(消息池): 负责关联线程以及消息的分发,在该线程下从 MessageQueue 获取 Message,分发给Handler,Looper 建立的时候会建立一个MessageQueue,调用 loop()方法的时候消息循环开
    始,其中会不断调用 messageQueuenext()方法,当有消息就处理,不然阻塞在 messageQueuenext()方法中。当 Looperquit()被调用的时候会调用messageQueuequit(),此时 next()会返回 null,而后 loop()方法也就跟着退出。

流程:
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。

  • 在主线程建立的时候会建立一个 Looper,同时也会在在Looper 内部建立一个消息队列。而在创键 Handler 的时候取出当前线程的 Looper,并经过该 Looper 对象得到消息队列,而后 Handler 在子线程中经过MessageQueue.enqueueMessage 在消息队列中添加一条 Message。
  • 经过 Looper.loop() 开启消息循环不断轮询调用MessageQueue.next(),取得对应的 Message 而且经过 Handler.dispatchMessage 传递给 Handler,最终调用 Handler.handlerMessage 处理消息。
二、一个线程可否建立多个 Handler,Handler 跟 Looper 之间的对应关系 ?

参考回答:

  • 一个 Thread 只能有一个 Looper,一个 MessageQueen,能够有多个 Handler
  • 以一个线程为基准,他们的数量级关系是: Thread(1) :Looper(1) : MessageQueue(1) : Handler(N)
三、软引用跟弱引用的区别

参考回答:

  • 软引用(SoftReference): 若是一个对象只具备软引用,则内存空间充足时,垃圾回收器就不会回收它;若是内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就能够一直被程序使用。
  • 弱引用(WeakReference): 若是一个对象只具备弱引用,那么在垃圾回收器线程扫描的过程当中,一旦发现了只具备弱引用的对象,无论当前内存空间足够与否,都会回收它的内存。
  • 二者之间根本区别在于: 只具备弱引用的对象拥有更短暂的生命周期,可能随时被回收。而只具备软引用的对象只有当内存不够的时候才被回收,在内存足够的时候,一般不被回收。
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
    四、Handler 引发的内存泄露缘由以及最佳解决方案

    参考回答:
    泄露缘由:Handler 容许咱们发送延时消息,若是在延时期间用户关闭了 Activity,那么该 Activity 会泄露。 这个泄露是由于 Message 会持有 Handler,而又由于 Java 的特性,内部类会持有外部类,使得 Activity 会被Handler 持有,这样最终就致使 Activity 泄露。

解决方案:将 Handler 定义成静态的内部类,在内部持有Activity 的弱引用,并在 AcitivityonDestroy()中调用 handler.removeCallbacksAndMessages(null)及时移除全部消息。

五、为何系统不建议在子线程访问 UI?

参考回答:
Android 的 UI 控件不是线程安全的,若是在多线程中并发访问可能会致使 UI 控件处于不可预期的状态

这时你可能会问为什么系统不对 UI 控件的访问加上锁机制呢?由于

  • 加锁机制会让 UI 访问逻辑变的复杂
  • 加锁机制会下降 UI 的访问效率,由于加锁会阻塞某些线程的执行
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
六、Looper 死循环为何不会致使应用卡死?

参考回答:

  • 主线程的主要方法就是消息循环,一旦退出消息循环,那么你的应用也就退出了,Looer.loop()方法可能会引发主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生 ANR 异常。
  • 形成 ANR 的不是主线程阻塞,而是主线程的 Looper 消息处理过程发生了任务阻塞,没法响应手势操做,不能及时刷新 UI。
  • 阻塞与程序无响应没有必然关系,虽然主线程在没有消息可处理的时候是阻塞的,可是只要保证有消息的时候可以马上处理,程序是不会无响应的。
七、使用 Handler 的 postDealy 后消息队列会有什么变化?

参考回答:
若是队列中只有这个消息,那么消息不会被发送,而是计算到时唤醒的时间,先将 Looper 阻塞,到时间就唤醒它。但若是此时要加入新消息,该消息队列的对头跟 delay 时间相比更长,则插入到头部,按照触发时间进行排序,队头的时间最小、队尾的时间最大

八、能够在子线程直接 new 一个 Handler 吗?怎么作?

参考回答:
不能够,由于在主线程中,Activity 内部包含一个 Looper 对象,它会自动管理 Looper,处理子线程中发送过来的消息。而对于子线程而言,没有任何对象帮助咱们维护 Looper 对象,因此须要咱们本身手动维护。因此要在子线程开启 Handler 要先建立 Looper,并开启 Looper 循环

//代码示例
  new Thread(new Runnable() {
             @Override
             public void run() {
                looper.prepare();
                new Handler() {
                    @Override
                     public void handlerMessage(Message msg) {
                        super.handleMessage(msg);
                     }
                     looper.loop();
                }
     }).start();
九、Message 能够如何建立?哪一种效果更好,为何?

参考回答: 能够经过三种方法建立:

  • 直接生成实例 Message m = new Message
  • 经过 Message m = Message.obtain
  • 经过 Message m = mHandler.obtainMessage()

后二者效果更好,由于 Android 默认的消息池中消息数量是 10,然后
二者是直接在消息池中取出一个 Message 实例,这样作就能够避免多
生成 Message 实例。

三丶IPC

1 丶Android 中进程和线程的关系和区别?

参考回答:

  • 线程是 CPU 调度的 最小单元,同时线程是一种 有限的系统资源
  • 进程通常指一个执行单元,在 PC 和移动设备上一个程序或则一个应用
  • 通常来讲,一个 App 程序 至少有一个进程,一个进程 至少有一个线程(包含与被包含的关系), 通俗来说就是,在App 这个工厂里面有一个进程,线程就是里面的生产线,但主线程(主生产线)只有一条,而子线程(副生产线)能够有多个
  • 进程有本身独立的地址空间,而进程中的线程共享此地址空间,均可以 并发执行
2 、如何开启多进程 ? 应用是否能够开启 N 个进程 ?

参考回答:

  • AndroidMenifest 中给四大组件指定属性android:process 开启多进程模式
  • 在内存容许的条件下能够开启 N 个进程
    3 、为什么须要 IPC ?多进程通讯可能会出现的问题?

    参考回答:
    全部运行在不一样进程的四大组件(Activity、Service、Receiver丶ContentProvider)共享数据都会失败,这是因为 Android 为每一个应用分配了独立的虚拟机,不一样的虚拟机在内存分配上有不一样的地址空间,这会致使在不一样的虚拟机中访问同一个类的对象会产生多份副本。好比经常使用例子( 经过开启多进程获取更大内存空间、两个或则多个应用之间共享数据、微信全家桶)

通常来讲,使用多进程通讯会形成以下几方面的问题

  • 静态成员和单例模式彻底失效: 独立的虚拟机形成
  • 线程同步机制彻底实效: 独立的虚拟机形成
  • SharedPreferences的可靠性降低: 这是由于 Sp 不支持两个进程并发进行读写,有必定概率致使数据丢失
  • Application 会屡次建立: Android 系统在建立新的进程会分配独立的虚拟机,因此这个过程其实就是启动一个应用的过程,天然也会建立新的Application
4 丶Android 中 IPC 方式、各类方式优缺点,为何选择 Binder

参考回答:
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
与 Linux 上传统的 IPC 机制,好比 System V,Socket 相比,Binder 好在哪呢?
传输效率高、可操做性强: 传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从 Android进程架构角度分析:对于消息队列、Socket 和管道来讲,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝,如图:
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
而对于 Binder 来讲,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程,如图:
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
因为共享内存操做复杂,综合来看,Binder 的传输效率是最好的。

实现 C/S 架构方便: Linux 的众 IPC 方式除了 Socket 之外都不是基于 C/S 架构,而 Socket 主要用于网络间的通讯且传输效率较低。Binder 基于 C/S 架构 ,Server 端与Client 端相对独立,稳定性较好。
安全性高: 传统 Linux IPC 的接收方没法得到对方进程可靠的 UID/PID,从而没法鉴别对方身份;而 Binder 机制为每一个进程分配了 UID/PID 且在 Binder 通讯时会根据UID/PID 进行有效性检测。

5 、Binder机制的左右和原理

参考回答:
Linux 系统将一个进程分为 用户空间和 内核空间。对于进程之间来讲,用户空间的数据不可共享,内核空间的数据可共享,为了保证安全性和独立性,一个进程不能直接操做或者访问另外一个进程,即 Android 的进程是相互独立、隔离的,这就须要跨进程之间的数据通讯方式
都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
一次完整的 Binder IPC 通讯过程一般是这样:

  • 首先 Binder 驱动在内核空间建立一个数据接收缓存区;
  • 接着在内核空间开辟一块内核缓存区,创建内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;
  • 发送方进程经过系统调用 copyfromuser() 将数据 copy 到内核中的内核缓存区,因为内核缓存区和接收进程的用户空间存在内存映射,所以也就至关于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通讯。
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
6 、Binder 框架中 ServiceManager的做用

参考回答:

  • Binder 框架 是基于 C/S 架构的。由一系列的组件组成,包括 Client、Server、ServiceManager、Binder 驱动,其中Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
  • Server&Client: 服务器&客户端。在 Binder 驱动和Service Manager 提供的基础设施上,进行 Client-Server 之间的通讯。
  • ServiceManager(如同 DNS 域名服务器)服务的管理者,将 Binder 名字转换为 Client 中对该 Binder的引用,使得 Client 能够经过 Binder 名字得到Server 中 Binder 实体的引用。
  • Binder 驱动(如同路由器): 负责进程之间 binder通讯的创建,传递,计数管理以及数据的传递交互等底层支持
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
7丶Bundle 传递对象为何须要序列化?Serialzable 和 Parcelable

参考回答:

  • 由于 bundle 传递数据时只支持基本数据类型,因此在传递对象时须要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象能够在网络、IPC(好比启动另外一个进程的 Activity、Service 和 Reciver)之间进行传输,也能够存储到本地。
  • 序列化实现的两种方式:实现 Serializable/Parcelable接口。不一样点如图:
    都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。
8 、讲讲 AIDL ?原理是什么?如何优化多模块都使用 AIDL

参考回答:
AIDL(Android Interface Definition Language,Android接口定义语言):若是在一个进程中要调用另外一个进程中对象的方法,可以使用 AIDL 生成可序列化的参数,AIDL 会生成一个服务端对象的代理类,经过它客户端实现间接调用服务端对象的方法

AIDL 的本质是系统提供了一套可快速实现 Binder 的工具。关键类和方法:

  • AIDL 接口: 继承 Interface
  • Stub 类: Binder 的实现类,服务端经过这个类来提供服务。
  • Proxy 类: 服务器的本地代理,客户端经过这个类调用服务器的方法。
  • asInterface() 客户端调用,将服务端的返回的Binder 对象,转换成客户端所须要的 AIDL 接口类型对象。若是客户端和服务端位于统一进程,则直接返回 Stub 对象自己,不然返回系统封装后的Stub.proxy 对象
  • asBinder()根据当前调用状况返回代理 Proxy 的Binder 对象。
  • onTransact() 运行服务端的 Binder 线程池中,当客户端发起跨进程请求时,远程请求会经过系统底层封装后交由此方法来处理。
  • transact() 运行在客户端,当客户端发起远程请求的同时将当前线程挂起。以后调用服务端的onTransact()直到远程请求返回,当前线程才继续执行。

当有多个业务模块都须要 AIDL 来进行 IPC,此时须要为每一个模块建立特定的 aidl 文件,那么相应的 Service 就会不少。必然会出现系统资源耗费严重、应用过分重量级的问题。解决办法是创建 Binder 链接池,即将每一个业务模块的Binder 请求统一转发到一个远程 Service 中去执行,从而避免重复建立 Service。

工做原理: 每一个业务模块建立本身的 AIDL 接口并实现此接口,而后向服务端提供本身的惟一标识和其对应的 Binder 对象。服务端只须要一个 Service,服务器提供一个 queryBinder 接口,它会根据业务模块的特征来返回相应的 Binder 对象,不一样的业务模块拿到所需的 Binder 对象后就可进行远程方法的调用了

查看完整的PDF版
(更多完整项目下载。未完待续。源码。图文知识后续上传github。)
能够联系我获取完整PDF
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)

都说衣不如新人不如故,技术是学新不学旧的?IPC+view+Handler+线程。

相关文章
相关标签/搜索