一般来说 一个 APK 只有一个进程 但是也有一个 APK 里面有多个进程的情况 , 进程与进程之间怎么互相通信呢 这需要用到 IPC 机制了 进程里面有什么呢 ?

 个人理解 

1 有 java class  由 vm (Google 包装了 jvm 来编译 java 文件)  为了避免商业纠纷 .   所以里面还有 vm 对象 , 还有 c/c++ 代码 直接由 cpu 来调用 通过 jni 和 java 进行交互 通过 ndk 环境 和 命令编译成 so 本地库 ,为什么要这样做开发呢  因为 java 虽然是可以一次编译多处运行 但是 性能上 不如 c/c++ 直接和 cpu 来解释了 一些对性能要求高的 游戏 APP 播放器得 难免需要 这样的混合开发 

2  除此之外进程当中还 包含了 主线程 MainThread 我们可以把它理解为不死 一直被CPU在执行的 这里可能不太好理解 , 你可以想象 Windows 电脑的桌面 大家都很熟悉的蓝色桌面 也可以把它看做一个不死的主线程 虽然可能你有时候没有操作它 但是它一直在等待你去点击 ,Android 的 主线程 也可以这么理解 比如它一直在等待你去点击屏幕等 它的主要职能 还是用来处理 UI 和事件 (为什么说主要 Android 14 以前是允许 主线程还去做耗时操作的 比如请求网络 操作数据库等 这样导致界面非常卡顿 用户体验极其差 所以 Android 14 以后 Google 强制要求 耗时操作放入子线程执行 ,所有我们在 14 以后版本 MainThread 中做耗时操作 会被抛出 ANR 的异常 application not repsone 在 Android 四大组件中分别都有它们抛出 anr 异常的时间 ) 所以我们也把 主线程 叫做 UI 线程 , 另外需要提到的是  MainThread 还需要 MessageQnun 和 looper 来配合 , 当主线程 把当前的 UI 事件处理完成以后 它又回去 MessageQnun 去查看有没有新的任务 这个是 依赖 looper , looper Android 源码里面 有个 死循环  这可能也是我们平时通常叫他轮询器的原因吧 (handler 机制) 话题说远了 我们回归进程正题  说到进程我们不得不提到 manifest 文件 相信大家都不陌生 manifest 是 Android 的总配置文件  config file 也称清单文件  里面包含了 包名 最大最小 Android 兼容版本 以及 权限声明 和 Android 的四大组件 如何在一个 apk 中配置多个不同进程  四大组件下 有个 属性 


android:process



如果你在配置 四大组建的时候 不为其配置 这个属性 这个 activity 或者 service 或者 receiver  就是在默认进程当中执行


<service
            android:name="io.rong.push.PushService"
            android:process="io.rong.push" >
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />

                <action android:name="io.rong.push" />
            </intent-filter>
        </service>



例如上面代码片段 是从 manifest 中摘取出来的 表示 这个 名为 pushService 的 服务 是在 io.rong.push 中运行的  

说了这么多 大家可能想问 我为什么一定要多进程 就算进程之间可以通过 IPC 实现夸进程访问 但是这样效率也比都在一个进程中互相调用来的慢 学之然 必知其所以然 Android 为什么要设计 这样的架构的 应用场景在哪里呢? 例如 IM 即时通讯 我的主进程 通过长连接来实时收到对方传递的消息 但是一旦因为一些特殊原因 或者 用户杀死了主进程 这样消息就不接收了? 这样也没有一个及时性了 所以此处你还设计了其他进程 来接收你主进程被杀死以后 来实时接收消息 我们一般把这个消息称作 push 消息


两个进程在一个 APP 中不能直接互相通讯和访问  这是因为安全机制来设定的 所以只能通过 IPC 的 IBinder 接口 下面我们来了解一下 IBinder 的定义与实现

Androidroid 应用处于后台会继续走网络请求吗 android app process_IBnder


我们先来看看 IBinder 接口当中有什么方法  查阅源码


Androidroid 应用处于后台会继续走网络请求吗 android app process_IBnder_02


其中最主要的 方法 transact()  client 调用它 透过 IPC 调用到 remote 的 onTransact() 



/**
     * Perform a generic operation with the object.
     * 
     * @param code The action to perform.  This should
     * be a number between {@link #FIRST_CALL_TRANSACTION} and
     * {@link #LAST_CALL_TRANSACTION}.
     * @param data Marshalled data to send to the target.  Must not be null.
     * If you are not sending any data, you must create an empty Parcel
     * that is given here.
     * @param reply Marshalled data to be received from the target.  May be
     * null if you are not interested in the return value.
     * @param flags Additional operation flags.  Either 0 for a normal
     * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
     */
    public boolean transact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException;



Parcel data 参数 为我们传过去的 序列化数据  Parcel reply 为 remote 回传的数据  对于 IBinder 接口 我们使用与其他 interface 无异 也是需要来实现 implements 它


另外 remote 需要编写 IBinderProxy 两个都是 IBinder 的实现类    一端的 transact() 来调用 另外一端的  onTransact() , onTransact() 为可复写的抽象方法


init() 和 execTransact? c/c++ 本地程序来调用? 但是在源码类没有找到这个方法和字段 猜测可能高版本 Android 已去 ..... 未完待续 (文章是笔者个人理解角度撰写 如有不正确的地方欢迎吐槽评论加指正)