Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划 (二)
2012-10-31 09:15
507 查看
前面我们说到,我们在这里举的例子包含了一个Server端和一个Client端实现,其中, Server端就是通过前面一个构造函数来创建一个匿名共享内存文件,接着,Client端过Binder进程间通信机制来向Server请求这个匿名共享内存的文件描述符,有了这个文件描述符之后,就可以通过后面一个构造函数来共享这个内存文件了。
因为涉及到Binder进程间通信,我们首先定义好Binder进程间通信接口。Binder进程间通信机制的相关介绍,请参考前面一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划,这里就不详细介绍了,直接进入主题。
首先在源代码工程的packages/experimental目录下创建一个应用程序工程目录Ashmem。关于如何获得Android源代码工程,请参考在Ubuntu上下载、编译和安装Android最新源代码一文;关于如何在Android源代码工程中创建应用程序工程,请参考在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务一文。这里,工程名称就是Ashmem了,它定义了一个路径为shy.luo.ashmem的package,这个例子的源代码主要就是实现在这里了。下面,将会逐一介绍这个package里面的文件。
这里要用到的Binder进程间通信接口定义在src/shy/luo/ashmem/IMemoryService.java文件中:
[java] view plaincopyprint?
package shy.luo.ashmem;
import android.util.Log;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
public interface IMemoryService extends IInterface {
public static abstract class Stub extends Binder implements IMemoryService {
private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";
public Stub() {
attachInterface(this, DESCRIPTOR);
}
public static IMemoryService asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IMemoryService) {
return (IMemoryService)iin;
}
return new IMemoryService.Stub.Proxy(obj);
}
public IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getFileDescriptor: {
data.enforceInterface(DESCRIPTOR);
ParcelFileDescriptor result = this.getFileDescriptor();
reply.writeNoException();
if (result != null) {
reply.writeInt(1);
result.writeToParcel(reply, 0);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_setValue: {
data.enforceInterface(DESCRIPTOR);
int val = data.readInt();
setValue(val);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements IMemoryService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
ParcelFileDescriptor result;
try {
data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);
reply.readException();
if (0 != reply.readInt()) {
result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
} else {
result = null;
}
} finally {
reply.recycle();
data.recycle();
}
return result;
}
public void setValue(int val) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);
reply.readException();
} finally {
reply.recycle();
data.recycle();
}
}
}
static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;
static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
}
[java] view plaincopyprint?
package shy.luo.ashmem;
import android.util.Log;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
public interface IMemoryService extends IInterface {
public static abstract class Stub extends Binder implements IMemoryService {
private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";
public Stub() {
attachInterface(this, DESCRIPTOR);
}
public static IMemoryService asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IMemoryService) {
return (IMemoryService)iin;
}
return new IMemoryService.Stub.Proxy(obj);
}
public IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getFileDescriptor: {
data.enforceInterface(DESCRIPTOR);
ParcelFileDescriptor result = this.getFileDescriptor();
reply.writeNoException();
if (result != null) {
reply.writeInt(1);
result.writeToParcel(reply, 0);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_setValue: {
data.enforceInterface(DESCRIPTOR);
int val = data.readInt();
setValue(val);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements IMemoryService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
ParcelFileDescriptor result;
try {
data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);
reply.readException();
if (0 != reply.readInt()) {
result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
} else {
result = null;
}
} finally {
reply.recycle();
data.recycle();
}
return result;
}
public void setValue(int val) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);
reply.readException();
} finally {
reply.recycle();
data.recycle();
}
}
}
static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;
static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
}
这里主要是定义了IMemoryService接口,它里面有两个调用接口:
[java] view plaincopyprint?
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
[java] view plaincopyprint?
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
同时,还分别定义了用于Server端实现的IMemoryService.Stub基类和用于Client端使用的代理IMemoryService.Stub.Proxy类。关于Binder进程间通信机制在应用程序框架层的Java接口定义,请参考前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析一文。
因为涉及到Binder进程间通信,我们首先定义好Binder进程间通信接口。Binder进程间通信机制的相关介绍,请参考前面一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划,这里就不详细介绍了,直接进入主题。
首先在源代码工程的packages/experimental目录下创建一个应用程序工程目录Ashmem。关于如何获得Android源代码工程,请参考在Ubuntu上下载、编译和安装Android最新源代码一文;关于如何在Android源代码工程中创建应用程序工程,请参考在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务一文。这里,工程名称就是Ashmem了,它定义了一个路径为shy.luo.ashmem的package,这个例子的源代码主要就是实现在这里了。下面,将会逐一介绍这个package里面的文件。
这里要用到的Binder进程间通信接口定义在src/shy/luo/ashmem/IMemoryService.java文件中:
[java] view plaincopyprint?
package shy.luo.ashmem;
import android.util.Log;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
public interface IMemoryService extends IInterface {
public static abstract class Stub extends Binder implements IMemoryService {
private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";
public Stub() {
attachInterface(this, DESCRIPTOR);
}
public static IMemoryService asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IMemoryService) {
return (IMemoryService)iin;
}
return new IMemoryService.Stub.Proxy(obj);
}
public IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getFileDescriptor: {
data.enforceInterface(DESCRIPTOR);
ParcelFileDescriptor result = this.getFileDescriptor();
reply.writeNoException();
if (result != null) {
reply.writeInt(1);
result.writeToParcel(reply, 0);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_setValue: {
data.enforceInterface(DESCRIPTOR);
int val = data.readInt();
setValue(val);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements IMemoryService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
ParcelFileDescriptor result;
try {
data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);
reply.readException();
if (0 != reply.readInt()) {
result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
} else {
result = null;
}
} finally {
reply.recycle();
data.recycle();
}
return result;
}
public void setValue(int val) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);
reply.readException();
} finally {
reply.recycle();
data.recycle();
}
}
}
static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;
static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
}
[java] view plaincopyprint?
package shy.luo.ashmem;
import android.util.Log;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
public interface IMemoryService extends IInterface {
public static abstract class Stub extends Binder implements IMemoryService {
private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";
public Stub() {
attachInterface(this, DESCRIPTOR);
}
public static IMemoryService asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IMemoryService) {
return (IMemoryService)iin;
}
return new IMemoryService.Stub.Proxy(obj);
}
public IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getFileDescriptor: {
data.enforceInterface(DESCRIPTOR);
ParcelFileDescriptor result = this.getFileDescriptor();
reply.writeNoException();
if (result != null) {
reply.writeInt(1);
result.writeToParcel(reply, 0);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_setValue: {
data.enforceInterface(DESCRIPTOR);
int val = data.readInt();
setValue(val);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements IMemoryService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
ParcelFileDescriptor result;
try {
data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);
reply.readException();
if (0 != reply.readInt()) {
result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
} else {
result = null;
}
} finally {
reply.recycle();
data.recycle();
}
return result;
}
public void setValue(int val) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);
reply.readException();
} finally {
reply.recycle();
data.recycle();
}
}
}
static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;
static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;
}
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
}
package shy.luo.ashmem; import android.util.Log; import android.os.IInterface; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.RemoteException; public interface IMemoryService extends IInterface { public static abstract class Stub extends Binder implements IMemoryService { private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService"; public Stub() { attachInterface(this, DESCRIPTOR); } public static IMemoryService asInterface(IBinder obj) { if (obj == null) { return null; } IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR); if (iin != null && iin instanceof IMemoryService) { return (IMemoryService)iin; } return new IMemoryService.Stub.Proxy(obj); } public IBinder asBinder() { return this; } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getFileDescriptor: { data.enforceInterface(DESCRIPTOR); ParcelFileDescriptor result = this.getFileDescriptor(); reply.writeNoException(); if (result != null) { reply.writeInt(1); result.writeToParcel(reply, 0); } else { reply.writeInt(0); } return true; } case TRANSACTION_setValue: { data.enforceInterface(DESCRIPTOR); int val = data.readInt(); setValue(val); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements IMemoryService { private IBinder mRemote; Proxy(IBinder remote) { mRemote = remote; } public IBinder asBinder() { return mRemote; } public String getInterfaceDescriptor() { return DESCRIPTOR; } public ParcelFileDescriptor getFileDescriptor() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); ParcelFileDescriptor result; try { data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0); reply.readException(); if (0 != reply.readInt()) { result = ParcelFileDescriptor.CREATOR.createFromParcel(reply); } else { result = null; } } finally { reply.recycle(); data.recycle(); } return result; } public void setValue(int val) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(DESCRIPTOR); data.writeInt(val); mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0); reply.readException(); } finally { reply.recycle(); data.recycle(); } } } static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0; static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1; } public ParcelFileDescriptor getFileDescriptor() throws RemoteException; public void setValue(int val) throws RemoteException; }
这里主要是定义了IMemoryService接口,它里面有两个调用接口:
[java] view plaincopyprint?
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
[java] view plaincopyprint?
public ParcelFileDescriptor getFileDescriptor() throws RemoteException;
public void setValue(int val) throws RemoteException;
public ParcelFileDescriptor getFileDescriptor() throws RemoteException; public void setValue(int val) throws RemoteException;
同时,还分别定义了用于Server端实现的IMemoryService.Stub基类和用于Client端使用的代理IMemoryService.Stub.Proxy类。关于Binder进程间通信机制在应用程序框架层的Java接口定义,请参考前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析一文。
相关文章推荐
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划(一)
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划 (三)
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划 (四)
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划 (五)
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析(上)
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析