导航:首页 > 操作系统 > aidlandroid跨进程

aidlandroid跨进程

发布时间:2022-09-02 23:13:20

android跨进程通信之AIDL机制和广播机制的异同

http://blog.csdn.net/java_xxoo_android/article/details/46352445

② aidl(android idl files)

为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procere Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

③ Android跨进程通信

本文整理和引用他人的笔记,旨在个人复习使用。

参考链接:

https://blog.csdn.net/fanleiym/article/details/83894399

https://github.com/274942954/AndroidCollection/blob/master/Docs/Android%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB.md#%E8%BF%9B%E7%A8%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F

https://www.kaelli.com/4.html

https://carsonho.blog.csdn.net/article/details/73560642?utm_medium=distribute.pc_relevant.none-task-blog--1.e_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog--1.e_weight

默认情况下,一个app只会运行在一个进程中,进程名为app的包名。

1. 分散内存的占用

Android系统对每个应用进程的内存占用是有限制的,占用内存越大的进程,被系统杀死的可能性就越大。使用多进程可以减少主进程占用的内存,避免OOM问题,降低被系统杀死的概率。

2. 实现多模块

一个成熟的应用一定是多模块化的。项目解耦,模块化,意味着开辟新的进程,有独立的JVM,带来数据解耦。模块之间互不干预,团队并行开发,同时责任分工也很明确。

3. 降低程序奔溃率

子进程崩溃不会影响主进程的运行,能降低程序的崩溃率。

4. 实现一些特殊功能

比如可以实现推送进程,使得主进程退出后,能离线完成消息推送服务。还可以实现守护进程,来唤醒主进程达到保活目的。还可以实现监控进程专门负责上报bug,进而提升用户体验。

android:process 属性的值以冒号开头的就是 私有进程 ,否则就是 公有进程 。当然命名还需要符合规范,不能以数字开头等等。

1. 前台进程

2. 可见进程

3. 服务进程

4. 后台进程

5. 空进程

Android 会将进程评定为它可能达到的最高级别。另外服务于另一进程的进程其级别永远不会低于其所服务的进程。

创建新的进程时会创建新的Application对象,而我们通常在Application的onCreate方法中只是完成一些全局的初始化操作,不需要多次执行。

解决思路:获取当前进程名,判断是否为主进程,只有主进程的时候才执行初始化操作

获取当前进程名的两种方法:

Application中判断是否是主进程(方法1例子):

Serializable 和 Parcelable是数据序列化的两种方式,Android中只有进行序列化过后的对象才能通过intent和Binder传递。

通常序列化后的对象完成传输后,通过反序列化获得的是一个新对象,而不是原来的对象。

Serializable是java接口,位于java.io的路径下。Serializable的原理就是把Java对象序列化为二进制文件后进行传递。Serializable使用起来非常简单,只需直接实现该接口就可以了。

Parcelable是Google为了解决Serializable效率低下的问题,为Android特意设计的一个接口。Parcelable的原理是将一个对象完全分解,分解成可以传输的数据类型(如基本数据类型)再进行传递。

通常需要存到本地磁盘的数据就使用Serializable,其他情况就使用效率更高的Parcelable。

IPC 即 Inter-Process Communication (进程间通信)。Android 基于 Linux,而 Linux 出于安全考虑,不同进程间不能之间操作对方的数据,这叫做“进程隔离”。

每个进程的虚拟内存空间(进程空间)又被分为了 用户空间和内核空间 进程只能访问自身用户空间,只有操作系统能访问内核空间。

由于进程只能访问自身用户空间,因此在传统的IPC中,发送进程需要通过_from_user(系统调用)将数据从自身用户空间拷贝到内核空间,再由接受进程通过_to_user从内核空间复拷贝到自身用户空间,共需要拷贝2次,效率十分低下。Android采用的是Binder作为IPC的机制,只需复制一次。

Binder翻译过来是粘合剂,是进程之间的粘合剂。

Binder IPC通信的底层原理是 通过内存映射(mmap),将接收进程的用户空间映射到内核空间 ,有了这个映射关系,接收进程就能通过用户空间的地址获得内核空间的数据,这样只需发送进程将数据拷贝到内核空间就可完成通讯。

一次完整的Binder IPC通信:

从IPC的角度看,Binder是一种跨进程通信机制(一种模型),Binder 是基于 C/S 架构的,这个通信机制中主要涉及四个角色:Client、Server、ServiceManager和Binder驱动。

Client、Server、ServiceManager都是运行在用户空间的进程,他们通过系统调用(open、mmap 和 ioctl)来访问设备文件/dev/binder,从而实现与Binder驱动的交互。Binder驱动提供进程间通信的能力(负责完成一些底层操作,比如开辟数据接受缓存区等),是Client、Server和ServiceManager之间的桥梁。

Client、Server就是需要进行通信两个的进程,通信流程:

细心的你一定发现了,注册服务和获得服务本身就是和ServiceManager进行跨进程通信。其实和ServiceManager的通信的过程也是获取Binder对象(早已创建在Binder驱动中,携带了注册和查询服务等接口方法)来使用,所有需要和ServiceManager通信的进程,只需通过0号引用,就可以获得这个Binder对象了。

AIDL内部原理就是基于Binder的,可以借此来分析Binder的使用。

AIDL是接口定义语言,简短的几句话就能定义好一个复杂的、内部有一定功能的java接口。

先看看ICallBack.aidl文件,这里定义了一个接口,表示了服务端提供的功能。

被定义出来的java接口继承了IInterface接口,并且内部提供了一个Stub抽象类给服务端(相当于封装了一下,服务端只需继承这个类,然后完成功能的里面具体的实现)。

参考: https://www.cnblogs.com/sqchen/p/10660939.html

(以下是添加了回调的最终实现,可以看参考链接一步一步来)

为需要使用的类,创建aidl文件。

系统会自动在main文件下生成aidl文件夹,并在该文件夹下创建相应目录。

在java相同路径下创建Student类,这里不能使用@Parcelize注解,否则会报错

创建IStudentService.aidl,定义了一个接口,该接口定义了服务端提供的功能。创建完后rebuild一下项目 (每次创建和修改定义接口文件都要rebuild一下)

创建在服务端的StudentService

可以看见有回调,说明客户端也提供了接口给服务端来回调(双向通信,此时客户端的变成了服务端),即ICallBack.aidl

客户端是通过Binder驱动返回的Binder调用StudentService里的具体实现方法

AIDL使用注意:

Messenger可以在不同进程中传递 Message 对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递了。Messenger 是一种轻量级的 IPC 方案,是对AIDL的封装,底层实现是 AIDL。

使用详见: https://blog.csdn.net/qq951127336/article/details/90678698

④ android开发中跨进程通信有几种方式

Android进程间通信的几种方式 定义多进程
第一:Android应用中使用多进程只有一个办法(用NDK的fork来做除外),就是在AndroidManifest.xml中声明组件时,用android:process属性来指定。
不知定process属性,则默认运行在主进程中,主进程名字为包名。
android:process = package:remote,将运行在package:remote进程中,属于全局进程,其他具有相同shareUID与签名的APP可以跑在这个进程中。
android:process = :remote ,将运行在默认包名:remote进程中,而且是APP的私有进程,不允许其他APP的组件来访问。
第二:多进程引发的问题
静态成员和单例失效:每个进程保持各自的静态成员和单例,相互独立。
线程同步机制失效:每个进程有自己的线程锁。
SharedPreferences可靠性下降:不支持并发写,会出现脏数据。
Application多次创建:不同进程跑在不同虚拟机,每个虚拟机启动会创建自己的Application,自定义Application时生命周期会混乱。
综上,不同进程拥有各自独立的虚拟机,Application,内存空间,由此引发一系列问题。
第三: 进程间通信
Bundle/Intent传递数据:
可传递基本类型,String,实现了Serializable或Parcellable接口的数据结构。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代码量少(仅一句),但I/O开销较大,一般用于输出到磁盘或网卡;后者实现代码多,效率高,一般用户内存间序列化和反序列化传输。
文件共享:
对同一个文件先后写读,从而实现传输,Linux机制下,可以对文件并发写,所以要注意同步。顺便一提,Windows下不支持并发读或写。
Messenger:
Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。
双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。
AIDL:
AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。
通过编写aidl文件来设计想要暴露的接口,编译后会自动生成响应的java文件,服务器将接口的具体实现写在Stub中,用iBinder对象传递给客户端,客户端bindService的时候,用asInterface的形式将iBinder还原成接口,再调用其中的方法。
ContentProvider:
系统四大组件之一,底层也是Binder实现,主要用来为其他APP提供数据,可以说天生就是为进程通信而生的。自己实现一个ContentProvider需要实现6个方法,其中onCreate是主线程中回调的,其他方法是运行在Binder之中的。自定义的ContentProvider注册时要提供authorities属性,应用需要访问的时候将属性包装成Uri.parse("content://authorities")。还可以设置permission,readPermission,writePermission来设置权限。 ContentProvider有query,delete,insert等方法,看起来貌似是一个数据库管理类,但其实可以用文件,内存数据等等一切来充当数据源,query返回的是一个Cursor,可以自定义继承AbstractCursor的类来实现。
Socket:
学过计算机网络的对Socket不陌生,所以不需要详细讲述。只需要注意,Android不允许在主线程中请求网络,而且请求网络必须要注意声明相应的permission。然后,在服务器中定义ServerSocket来监听端口,客户端使用Socket来请求端口,连通后就可以进行通信。

⑤ Android 进程间通信的几种实现方式

Android 进程间通信的几种实现方式

主要有4种方式:

这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。

主要实现原理:

由于应用程序之间不能共享内存。为了在不同应用程序之间交互数据(跨进程通讯),AndroidSDK中提供了4种用于跨进程通讯的方式进行交互数据,实现进程间通信主要是使用sdk中提供的4组组件根据实际开发情况进行实现数据交互。

详细实现方式:

Acitivity实现方式

Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过 Intent构造方法的第2个参数指定)。 在android系统中有很多应用程序提供了可以跨进程访问的Activity,例如,下面的代码可以直接调用拨打电话的Activity。

IntentcallIntent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:12345678");
startActivity(callIntent);


Content Provider实现方式

Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)

应用程序可以利用Content Provider完成下面的工作

1. 查询数据
2. 修改数据
3. 添加数据
4. 删除数据

Broadcast 广播实现方式

广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。这就象电台进行广播一样,听众只能被动地收听,而不能主动与电台进行沟通。在应用程序中发送广播比较简单。只需要调用sendBroadcast方法即可。该方法需要一个Intent对象。通过Intent对象可以发送需要广播的数据。


Service实现方式

常用的使用方式之一:利用AIDL Service实现跨进程通信

这是我个人比较推崇的方式,因为它相比Broadcast而言,虽然实现上稍微麻烦了一点,但是它的优势就是不会像广播那样在手机中的广播较多时会有明显的时延,甚至有广播发送不成功的情况出现。

注意普通的Service并不能实现跨进程操作,实际上普通的Service和它所在的应用处于同一个进程中,而且它也不会专门开一条新的线程,因此如果在普通的Service中实现在耗时的任务,需要新开线程。

要实现跨进程通信,需要借助AIDL(Android Interface Definition Language)。Android中的跨进程服务其实是采用C/S的架构,因而AIDL的目的就是实现通信接口。


总结

跨进程通讯这个方面service方式的通讯远远复杂于其他几种通讯方式,实际开发中Activity、Content Provider、Broadcast和Service。4种经常用到,学习过程中要对没种实现方式有一定的了解。

⑥ android中的跨进程是什么意思

android系统中应用程序之间不能共享内存。在不同应用程序之间进行的数据交换叫跨进程。
在android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨进程调用其他应用程序的Activity;Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操 作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。

⑦ Android开发中在哪些场合下会需要使用AIDL

严格来说,线程是共享资源的,所以线程之间是不存在通信的,Android里面的Handle是用来解决异步调用的,这个观念很重要,想明白了,代码也就写的更合理了。
进程之间内存等资源是隔离的,而AIDL,是Android提供的跨进程通信IPC工具Binder的具体使用方法,跟其他Linux跨进程通信(socket,管道,能存共享等)在概念上没啥差。所以要实现跨进程的内存访问(比如数据传输,函数跨进程同步调用等)就需要了AIDL了,当然了AIDL并不是Android中跨进程通信的唯一选择,socket(systemServer进程与zygote进程,pkms调用install进程,MountService与vold进程通信都是通过socket),共享内存(sqlite3查询就用了)等都可以用的,但是没有Binder通过AIDL好用罢了。

阅读全文

与aidlandroid跨进程相关的资料

热点内容
加密货币换平台 浏览:601
手机内存压缩软件 浏览:33
生成树是否与遍历算法有关 浏览:727
python强化学习迷宫 浏览:449
老包子解压视频 浏览:885
服务器注册是什么意思 浏览:418
程序员群体焦虑如何破局 浏览:584
程序员在广州上班 浏览:802
androidlinuxadt 浏览:512
广联达软件加密锁原装芯片 浏览:338
如何打开数据库服务器 浏览:310
kppm是什么app 浏览:538
python多个数组命名 浏览:192
a算法csdn 浏览:23
r720服务器什么年代 浏览:975
本地电脑怎么设置传奇服务器 浏览:1002
安卓10框架怎么制作 浏览:959
程序员退休工资待遇 浏览:609
湛江中文编程数控系统代理 浏览:419
openglandroid书 浏览:170