【内核研究】保证包裹内参数顺序aidl工具的使用(上)
来源:互联网 发布:网络支付清算平台 编辑:程序博客网 时间:2024/05/22 06:29
关于第二个问题,Android的SDK中提供了一个aidl工具,该工具可以把一个aidl文件转换为一个Java类文件,在该Java类文件,同时重载了transact和onTransact()方法,统一了存入包裹和读取包裹参数,从而使设计者可以把注意力放到服务代码本身上。
aidl工具不是必需的,对于有经验的程序员来讲,手工编写一个参数统一的包裹存入和包裹读出代码并不是一件复杂的事情。
接下来看aidl工具都做了什么。如本章第一节示例,此处依然假设要编写一个MusicPlayerService服务,服务中包含两个服务函数,分别是start()和stop()。那么,可以首先编写一个IMusicPlayerService.aidl文件。如以下代码所示:
package com.haiii.android.client; interface IMusicPlayerService{ boolean start(String filePath); void stop(); }
该文件的名称必须遵循一定的规范,第一个字母"I"不是必需的,但是,为了程序风格的统一,"I"的含义是IInterface类,即这是一个可以提供访问远程服务的类。后面的命名--MusicPlayerService对应的是服务的类名,可以是任意的,但是,aidl工具会以该名称命名输出的Java类。这些规则都只是Eclipse下ADT插件的默认规则,aidl本身只是一个命令行程序,借助命令行的话,则可以灵活指定输出文件的名称及位置。具体使用方法参照aidl的执行帮助信息。
http://developer.android.com/guide/components/aidl.html
aidl文件的语法基本类似于Java,package指定输出后的Java文件对应的包名。如果该文件需要引用其他Java类,则可以使用import关键字,但需要注意的是,包裹内只能写入以下三个类型的内容。
- Java原子类型,如int、long、String等变量。
- Binder引用。
- 实现了Parcelable的对象。
因此,基本上来讲,import所引用的Java类也只能是以上三个类型。
interface为关键字,有时会在interface前面加一个oneway,代表该service提供的方法都是没有返回值的,即都是void类型。
下面看看该aidl生成的IMusicPlayerService.java文件的代码。如下所示:
package com.haiii.client;public interface IMusicPlayerService extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.haiii.client.IMusicPlayerService { private static final java.lang.String DESCRIPTOR = "com.haiii.client.IMusicPlayerService"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.haiii.client.IMusicPlayerService interface, * generating a proxy if needed. */ public static com.haiii.client.IMusicPlayerService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.haiii.client.IMusicPlayerService))) { return ((com.haiii.client.IMusicPlayerService) iin); } return new com.haiii.client.IMusicPlayerService.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_start: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); boolean _result = this.start(_arg0); reply.writeNoException(); reply.writeInt(((_result) ? (1) : (0))); return true; } case TRANSACTION_stop: { data.enforceInterface(DESCRIPTOR); this.stop(); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.haiii.client.IMusicPlayerService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } public boolean start(java.lang.String filePath) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(filePath); mRemote.transact(Stub.TRANSACTION_start, _data, _reply, 0); _reply.readException(); _result = (0 != _reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } public void stop() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_start = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public boolean start(java.lang.String filePath) throws android.os.RemoteException; public void stop() throws android.os.RemoteException;}
- 【内核研究】保证包裹内参数顺序aidl工具的使用(上)
- 【内核研究】保证包裹内参数顺序aidl工具的使用(下)
- redis发布订阅(顺序保证,是否丢失,可靠性保证)研究
- 黑客内参-使用恶意软件将隐藏代码注入已知进程的渗透研究
- 摄像机的内参数和外参数
- Java 多线程 (PART VII) 使用join()方法保证线程的执行顺序
- OpenCV3.1.0的calibrateCamera()函数计算相机内参数
- 卡特兰数及栈出栈顺序问题的相关研究
- 链表开始前的准备 之 tools(工具)、包裹函数
- intrinsic parameters内参数求解
- 不使用(a+b)/2这种方式,求两个数的平均值(保证不会溢出)
- 使用python写的调内参的简易程序
- vue实例中data使用return包裹和不使用return包裹的区别
- PXA310 平台上的浮点数支持方案研究
- 如何保证线程执行的顺序
- tcp如何保证数据包的顺序传输
- Binder 框架(二)aidl的使用
- Android中AIDL的使用(一)
- HDU5047Sawtooth(java大数)
- Java网络编程
- mac系统下配置eclipse android开发环境方法
- 做个决定吧!
- 用相同cookies构造http请求的python代码实现
- 【内核研究】保证包裹内参数顺序aidl工具的使用(上)
- mysqldump 生成.gz文件
- android 中的栈
- NS3学习记录(一)---Ubuntu下安装NS3
- Android反射机制
- 大数处理
- 操作系统进程调度,优先级反转,调度策略
- NS3学习记录(二)---eclipse调试NS3配置
- OSX中php多进程安装pcntl