转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/111553746
本文出自【赵彦军的博客】

文章目录

  • 1、Android进程
  • 2、修改Android默认进程
  • 3、指定activity、Service进程
  • 4、activity进程间通信
  • 5、AIDL 简介
  • 6、activity、service 进程间通信 AIDL
  • 7、AIDL 传递复杂对象
  • 8、SharedPreferences 跨进程
  • 9、广播跨进程
  • 10、ContentProvider跨进程
    • 什么是ContentProvider ?
    • ContentProvider什么作用?
    • ContentProvider原理
    • ContentProvider优秀文章链接
  • 11、Socket跨进程通信
  • 12、文件共享跨进程
  • 13、Bundle跨进程
  • 14、MMKV

1、Android进程

android {compileSdkVersion 29buildToolsVersion "29.0.3"defaultConfig {applicationId "com.zhaoyanjun"minSdkVersion 16targetSdkVersion 29versionCode 1versionName "1.0"}
}

applicationId 为:com.zhaoyanjun,那项目运行起来,所有的 activityservice 默认运行在 com.zhaoyanjun 进程.

工具类:

package com.zhaoyanjun;import java.io.FileInputStream;
import java.io.IOException;/*** @author yanjun.zhao* @time 2020/12/16 11:01 AM* @desc*/
public class Process {/*** 获取当前进程名* @return*/public static String getCurrentProcessName() {FileInputStream in = null;try {String fn = "/proc/self/cmdline";in = new FileInputStream(fn);byte[] buffer = new byte[256];int len = 0;int b;while ((b = in.read()) > 0 && len < buffer.length) {buffer[len++] = (byte) b;}if (len > 0) {String s = new String(buffer, 0, len, "UTF-8");return s;}} catch (Throwable e) {e.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}return null;}
}

2、修改Android默认进程

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.zhaoyanjun"><applicationandroid:process=":appProcess"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.RecyclerViewDemo"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

在 application 标签下添加 android:process 属性可以修改Android默认的进程名字。进程的名字为:com.zhaoyanjun:appProcess , 这个修改是全局的,所有 activity 都默认运行在这个进程中。

3、指定activity、Service进程

activity 指定进程

<activityandroid:process=":remote"android:name=".MainActivity2">
</activity>


service 指定进程

<serviceandroid:process=":remote_service"android:name=".LibraryService">
</service>

4、activity进程间通信

MainActivity有一个 button 按钮,点击跳转到 MainActivity2

//MainActivity代码
findViewById<Button>(R.id.bt1).setOnClickListener {var intent = Intent(this, MainActivity2::class.java)intent.putExtra("key", "value1")startActivity(intent)
}

MainActivity2 指定进程

<activityandroid:process=":remote"android:name=".MainActivity2">
</activity>

MainActivity2 逻辑

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main2)var value = intent.getStringExtra("key")Log.d("zhaoyanjun", "MainActivity2 进程: ${Process.getCurrentProcessName()} 获取值: $value")
}

日志:

D/zhaoyanjun: MainActivity2 进程: com.zhaoyanjun:remote 获取值: value1

5、AIDL 简介

AIDL的语法十分简单,与Java语言基本保持一致,需要记住的规则有以下几点:

1、AIDL文件以 .aidl 为后缀名

2、 AIDL支持的数据类型分为如下几种:

  • 八种基本数据类型:bytecharshortintlongfloatdoubleboolean
    StringCharSequence
  • 实现了Parcelable接口的数据类型
  • List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
  • Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象

3、AIDL文件可以分为两类。一类用来声明实现了Parcelable接口的数据类型,以供其他AIDL文件使用那些非默认支持的数据类型。还有一类是用来定义接口方法,声明要暴露哪些接口给客户端调用,定向Tag就是用来标注这些方法的参数值。

3、定向Tag。定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为 in、out、inout 三种。

  • 其中 in 表示数据只能由客户端流向服务端,
  • out 表示数据只能由服务端流向客户端,而 inout 则表示数据可在服务端与客户端之间双向流通。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。定向Tag具体的使用差别后边会有介绍

4、明确导包。在AIDL文件中需要明确标明引用到的数据类型所在的包名,即使两个文件处在同个包名下

6、activity、service 进程间通信 AIDL

创建 IBookAidlInterface.aidl文件
创建 IBookAidlInterface 完成后,会在 main 目录下,创建 aidl 文件夹,并且会创建同名的包名,如下:

我们把默认的 basicTypes 方法删除,修改如下

interface IBookAidlInterface {String getTitle();void setTitle(String title);
}

下面创建 Service , 并指定进程名字:

 <serviceandroid:name=".MyService"android:enabled="true"android:exported="true"android:process=":remote" />

MyService 如下:

class MyService : Service() {private var binder: Binder = object : IBookAidlInterface.Stub() {override fun getTitle(): String {return "aidl->title"}override fun setTitle(title: String?) {Log.d("aidl", "service-setTitle:$title")}}override fun onBind(intent: Intent): IBinder {return binder}override fun onCreate() {super.onCreate()}
}

MainActivity 绑定Service

class MainActivity : AppCompatActivity() {private var iBookAidlInterface: IBookAidlInterface? = nullprivate var serviceConnection: ServiceConnection = object : ServiceConnection {override fun onServiceDisconnected(name: ComponentName?) {}override fun onServiceConnected(name: ComponentName?, service: IBinder?) {iBookAidlInterface = IBookAidlInterface.Stub.asInterface(service)var name = iBookAidlInterface?.titleLog.d("aidl", "getTitle: $name")iBookAidlInterface?.title = "我是一个title"}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)bindService()}/*** 绑定服务*/private fun bindService() {var intent = Intent(this, MyService::class.java)bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)}override fun onDestroy() {super.onDestroy()unbindService(serviceConnection)}
}

运行项目,日志如下:


可以看到,子进程 Service 和 主进程的 Activity 已经可以通信了。
github 地址:https://github.com/zyj1609wz/AndroidMultiProgress

7、AIDL 传递复杂对象

首先创建 Book 类,并且实现 Parcelable 接口。这里要注意,一定要实现 Parcelable 接口,因为只有实现 Parcelable 的复杂对象才能在 AIDL 中传递。

public class Book implements Parcelable {public String title;Book() {}protected Book(Parcel in) {title = in.readString();}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(title);}@Overridepublic int describeContents() {return 0;}public static final Creator<Book> CREATOR = new Creator<Book>() {@Overridepublic Book createFromParcel(Parcel in) {return new Book(in);}@Overridepublic Book[] newArray(int size) {return new Book[size];}};
}

同时在 aidl 目录中定义 Book.aidl 文件,并且声明 parcelable 属性。Book.aidl文件如下:

package com.yanjun.progress;parcelable Book;

下面我们修改 IBookAidlInterface.aidl 的方法,如下:

interface IBookAidlInterface {String getTitle();void setTitle(String title);Book getBook();void setBook(in Book book);
}

需要注意的是 setBook方法,一定要声明 Book 对象是 in属性,表明是 book 对象是从客户端流向服务端。

最后在 Service 里面实现接口就行了,如下:

class MyService : Service() {private var binder: Binder = object : IBookAidlInterface.Stub() {override fun getTitle(): String {return "aidl->title"}override fun setTitle(title: String?) {Log.d("aidl", "service-setTitle:$title")}override fun getBook(): Book {var book = Book()book.title = "书的名字"return book}override fun setBook(book: Book?) {}}override fun onBind(intent: Intent): IBinder ?{return binder}override fun onCreate() {super.onCreate()}
}

demo github 地址:https://github.com/zyj1609wz/AndroidMultiProgress

8、SharedPreferences 跨进程

SharedPreferences要实现跨进程通信,要遵循文件名字相同的规则。而且是同一个应用,两个进程间。
SharedPreferences之所以能实现跨进程,是因为SharedPreferences 数据存在SD卡的磁盘中,两个进程共用一个文件。

注意事项:

  • 虽然 SharedPreferences 可以实现跨进程,但是 Google 官方不建议使用,因为 Google 认为多个进程读同一个文件都是不安全的,Android 不保证该模式总是能正确的工作,建议使用 ContentProvider 替代多进程之间文件的共享。

额外话题 SharedPreferences 优化:

  • commit 是把内容同步提交到硬盘的,返回 boolean 表明修改是否提交成功
  • apply先立即把修改提交到内存,然后开启一个异步的线程提交到硬盘,并且如果提交失败,你不会收到任何通知,apply没有返回值 。
  • 使用了apply方式异步写sp的时候,每次apply()调用都会新增一个finisher。在有些系统生命周期事件发生的时候都会去检查已经提交的apply写操作是否完成,如果没有完成则阻塞主线程,造成 ANR
  • 当一个文件较大时,首次读取可能会较慢,每次写入也会较慢
  • 在不同模块使用多个文件存储的情况下,那么未被使用到的模块,不会被读取进内存
  • 当存储的valuejson或者html形式时,由于特殊符号较多,会占用更多的字符

如何解决 ANR :

  • 如果处理 SP的时候,使用commit方法替代apply,在保证调用时线程正确处理,并保证同一文件不使用多个线程写入的情况下,不会出现该ANR
  • 自查是否有一下子修改多个key-valueapply多次的情况,如有,可合并为put多次但apply一次

9、广播跨进程

Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理

10、ContentProvider跨进程

什么是ContentProvider ?

即 内容提供者,是 Android 四大组件之一

ContentProvider什么作用?

进程间 进行数据交互 & 共享,即跨进程通信

ContentProvider原理

ContentProvider的底层原理 = Android中的Binder机制

ContentProvider优秀文章链接

本来是想总结一下的,但是我发现了一篇写的很好的文章:
建议把文章和评论都看看,很有收获。

Android:关于ContentProvider的知识都在这里了!
Android中使用Contentprovider导致进程被杀死

11、Socket跨进程通信

优点:

  • 功能强大,可通过网络传输字节流,支持一对多实时并发通信

缺点:

  • 实现细节步骤稍繁琐,不支持直接的RPC

适用场景:

  • 网络间的数据交换

12、文件共享跨进程

优点

  • 简单易用

缺点:

  • 不适用高并发场景,并且无法做到进程间即时通信

适用场景:

  • 适用于无关发的情况下,交换简单的数据,对实时性要求不高的场景。

13、Bundle跨进程

优点

  • 简单易用

缺点:

  • 只能传输Bundle支持的数据类型

适用场景:

  • 四大组件间的进程间通信

14、MMKV

MMKV是国内微信团队开源的高性能 key-value组件,良好的支持Android跨进程通信,具体使用方法就自己看文档吧,这里不赘述了。

github: https://github.com/Tencent/MMKV/
中文文档:MMKV中文文档

Android 跨进程通信大总结相关推荐

  1. 【朝花夕拾】Android跨进程通信总结篇

    前言 原文:https://www.cnblogs.com/andy-songwei/p/10256379.html 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一. ...

  2. 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10256379.html],谢谢! 只要是面试高级工程师岗位,Android跨进程通信就是最受面 ...

  3. 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇...

    前言 原文:https://www.cnblogs.com/andy-songwei/p/10256379.html 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一. ...

  4. Android跨进程通信Binder机制与AIDL实例

    文章目录 进程通信 1.1 进程空间划分 1.2 跨进程通信IPC 1.3 Linux跨进程通信 1.4 Android进程通信 Binder跨进程通信 2.1 Binder简介 2.2 Binder ...

  5. Android 跨进程通信(一)

    Android 跨进程通信 Android 本身提供一四种方式进行实现跨进程通信,他们也分别是Android的四大组件.分别是:Activity,Content Provider,Broadcast和 ...

  6. Android - 跨进程通信(IPC) 另一种便捷实现 详解

    文章目录 1. 写在前面 2. 跨进程通信的实现 3. 扩展思考 4. 参考资料 1. 写在前面 看到此图有何感想,这是另一种便捷的实现方式,我们先来看看其它的几种方式. Android 进程间通信 ...

  7. 【Binder】Android 跨进程通信原理解析

    前言 在Android开发的过程中,用到跨进程通信的地方非常非常多,我们所使用的Activity.Service等组件都需要和AMS进行跨进程通信,而这种跨进程的通信都是由Binder完成的. 甚至一 ...

  8. Android跨进程通信

    一 多进程之间的通信 由于不同进程所拥有的地址是两块不同的地址空间,所以不能直接通过共享内存共享数据了. Linux常用跨进程通信方式:管道,信号量,共享内存,socket Android常用跨进程通 ...

  9. 使用AIDL+动态代理+运行时注解+反射 反手撸一套Android跨进程通信框架

    IPC 前言 跨进程通信方式 跨进程通信框架 涉及到的技术 使用Request-Response思想 IPCRequest IPCResponse RemoteService 服务端 客户端 附带 项 ...

最新文章

  1. 图像解码之一——使用libjpeg解码jpeg图片
  2. 【评估价格】采购申请中的价格
  3. 为jquery.AutoComplete添加触发事件
  4. Redis入门到入土教程_2 远程连接redis
  5. hihoCoder - 1079 - 离散化 (线段树 + 离散化)
  6. 哈佛结构 Linux,哈佛结构与冯诺依曼结构区别
  7. Quectel BC95-CNV 多频段、高性能、低功耗 LTE Cat NB2无线通信模块[移远通信]
  8. 怎么使用QQ音乐api搭建个人音乐站点
  9. WPS永久关闭热点、云服务、初始登陆界面
  10. 数据仓库系列7-ETL 子系统与技术
  11. 【零基础】speech driven animation中文安装使用指南
  12. 华为HCNA独家视频课程
  13. 一文看透 Kotlin 协程本质
  14. 鸟哥的linux私房菜_linux磁盘与文件系统管理
  15. MySQL数据库实操教程(25)——权限管理
  16. 无线通信模块定点传输-点对点的具体传输应用
  17. 地图不是领地尼克·格里尔的采访
  18. Excel VBA高级编程 - 根据关键字自动搜索,自动生成下拉菜单
  19. TM1814 WRGB的一种驱动方法:UART
  20. cass实体编码列表

热门文章

  1. php 输出答案,php 如何只输出最后生成的那个值??
  2. 五十三、开始算法刷题磨练
  3. 十、给小白看的第三篇Python基础教程
  4. 服务器运行jupyter notebook,解决办法
  5. 五、Requests库详细的用法
  6. 今日arXiv精选:Transformer专题论文推荐
  7. 如何搭建AIoT智能对话交互系统:技术解析和实操分享
  8. 从 Word2Vec 到 BERT
  9. 2019年“计算法学”夏令营即日起接收报名申请
  10. BZOJ2131免费的馅饼 DP+树状数组