Android系统匿名共享内存子系统Ashmem简要介绍和学(2)

前面我们说到,我们在这里举的例子包含了一个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文件中:

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接口,它里面有两个调用接口:

public ParcelFileDescriptor getFileDescriptor() throws RemoteException;   public void setValue(int val) throws RemoteException;  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjwwx.html