您的位置:首页 > 移动开发 > Android开发

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;

}

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接口源代码分析一文。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐