IPC基础
来源:互联网 发布:阿里云大数据分析 编辑:程序博客网 时间:2024/06/01 09:15
Android 系统中充斥着各种IPC。常见的例子:对系统状态栏的控制(StatusBar
和NavigationBar
)、对键盘的控制等等。了解IPC 的机制,对于Android 源码的理解也可以加深。以前有做过一些简单的aidl 的IPC,做一个简单回顾。
多进程回顾
进程和线程的区别?进程是一个执行单元,而线程是一个调度的单元。形象一点,一个进程代表了一个app,一个app 运行的时候会有一个主线程(UI线程)以及其它的一些线程,比如耗时操作放在其它线程等。
在一个app(进程)中处理的时候,更多的时候考虑的是线程同步(使用synchronized、锁等等)。在多个app (进程)之间处理的时候就需要进程间通信了。举个例子,做了一个用来清理内存的app(单独app)。现在做了一个新的app 想调用,就可以使用进程间通信了。
简单aidl
调用流程
1.书写aidl
文件,build
以后会生成java
文件。
interface IAddAidl { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ int add(int addA, int abbB);}
2.创建自己的Service
。
public class AddService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } IAddAidl.Stub mBinder = new IAddAidl.Stub() { @Override public int add(int addA, int addB) throws RemoteException { return addA + addB; } };}
3.绑定Service
。
IAddAidl mIAddAidl;ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIAddAidl = IAddAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mIAddAidl = null; }};bindService(new Intent(this, AddService.class), mConnection, Context.BIND_AUTO_CREATE);
4.调用
mIAddAidl.add(1, 1);
分析aidl
的调用
写完.aidl
以后,build
一下就会自动生成.java
文件。从上面的流程来看,绑定Service
的时候可以得到相应的IAddAidl
对象,最后调用的也是IAddAidl
对象。
1.绑定Service
的时候得到的IAddAidl
是什么。
// IAddAidl.java/*** Cast an IBinder object into an com.egos.samples.aidl.IAddAidl interface, generating a* proxy if needed.*/public static IAddAidl asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } // 通过传过来的IBinder对象来获取IInterface对象 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.egos.samples.aidl.IAddAidl))) { return ((IAddAidl) iin); } // 如果传过来的IBinder对象不满足的时候就会创建一个Proxy return new IAddAidl.Stub.Proxy(obj);}
注意这里有一个DESCRIPTOR
,代表的是Binder
的唯一标志符。bindService
回调onServiceConnected
返回的IBinder
对象,如果Service
和Activity
(或者Application
)在同一个进程,则返回的是Service.onBind
返回的对象,不在同一个进程中返回的是BinderProxy
对象。即如果Client
和Server
运行在不同的进程,则需要创建Proxy
对象。
2.创建Proxy
的逻辑,Proxy
实现了IAddAidl
。
private static class Proxy implements IAddAidl { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public int add(int addA, int abbB) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(addA); _data.writeInt(abbB); mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; }}
3.最终调用的是Proxy.add()
方法。
在add
方法中最终调用的是mRemote.transact
,传递了4个参数,分别是区分需要调用方法的一个id、方法所需要的参数、方法返回的结果以及一个flags。Transact
过程就是一个进程间通信。
问题
1.aidl
支持的数据类型。
- Java的原生类型(不包含short,
android.os.Parcel
不支持) - CharSequence和String
- List和Map(里面的元素必须备aidl支持)
- Parcelable,实现了Parcelable的对象
- aidl,aidl接口本身可以在aidl文件中使用。
然后上面还有问题,除了Java的原生类型以外,其它的类型都需要标上方向,in、out或者inout。(测试发现aidl本身也可以不写明)
in表示输入型参数(Server可以获取到Client传递过去的数据,但是不能对Client端的数据进行修改)
out表示输出型参数(Server获取不到Client传递过去的数据,但是能对Client端的数据进行修改)
inout表示输入输出型参数(Server可以获取到Client传递过去的数据,但是能对Client端的数据进行修改)。
举个例子。
void test2(Map map); // 错误void test2(in Map map); // 正确
aidl
中导入Parcelable
对象问题。
(1).需要在aidl
目录下先创建aidl
文件
// Person.aidlpackage com.egos.samples.aidl;parcelable Person;
(2).在Java文件下创建Person
类,注意需要实现Parcelable
接口。
- IPC基础
- IPC基础
- IPC基础
- IPC基础
- IPC基础
- IPC基础
- IPC基础小记
- Android IPC基础
- IPC基础概念介绍
- IPC基础概念
- System V IPC基础
- IPC机制---03 IPC基础概念介绍
- IPC(二)---IPC基础概念介绍
- ipc$基础入侵原理知识
- Android IPC基础概念介绍
- IPC基础小记 关于Binder
- IPC基础概念---Serializable接口
- IPC基础概念---Parcelable接口
- 【模板】【洛谷 P3382】三分
- Linux环境下运行mysql图形化数据库管理工具Navicat11.2.15 之Navicat11.2.15中文版 linux64位使用
- Fisher判别分析简述
- 回调-----小总结。
- 终端下vim无法输入问题解决, 无响应,
- IPC基础
- 神奇的拉普拉斯平滑(Laplacian Smoothing)及其在正则化上的应用~
- Linux中vi替换命令
- 面向对象(上)
- 关于各种无法解析的外部符号问题的相应解决方案
- 拉普拉斯平滑处理 Laplace Smoothing
- uva 11210 暴力搜索
- Kuberentes Ingress
- [李景山php] 单进程 php 的执行流程