Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃 (二)

broadviewbj發表於2012-10-31
這裡要用到的Binder程式間通訊介面定義在src/shy/luo/ashmem/IMemoryService.java檔案中:

  1. package shy.luo.ashmem;  
  2.   
  3. import android.util.Log;  
  4. import android.os.IInterface;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7. import android.os.Parcel;  
  8. import android.os.ParcelFileDescriptor;  
  9. import android.os.RemoteException;  
  10.   
  11. public interface IMemoryService extends IInterface {  
  12.     public static abstract class Stub extends Binder implements IMemoryService {  
  13.         private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";  
  14.   
  15.         public Stub() {  
  16.             attachInterface(this, DESCRIPTOR);  
  17.         }  
  18.   
  19.         public static IMemoryService asInterface(IBinder obj) {  
  20.             if (obj == null) {  
  21.                 return null;  
  22.             }  
  23.   
  24.             IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);  
  25.             if (iin != null && iin instanceof IMemoryService) {  
  26.                 return (IMemoryService)iin;  
  27.             }  
  28.   
  29.             return new IMemoryService.Stub.Proxy(obj);  
  30.         }  
  31.   
  32.         public IBinder asBinder() {  
  33.             return this;  
  34.         }  
  35.   
  36.         @Override   
  37.         public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {  
  38.             switch (code) {  
  39.             case INTERFACE_TRANSACTION: {  
  40.                 reply.writeString(DESCRIPTOR);  
  41.                 return true;  
  42.             }  
  43.             case TRANSACTION_getFileDescriptor: {  
  44.                 data.enforceInterface(DESCRIPTOR);  
  45.                   
  46.                 ParcelFileDescriptor result = this.getFileDescriptor();  
  47.                   
  48.                 reply.writeNoException();  
  49.                   
  50.                 if (result != null) {  
  51.                     reply.writeInt(1);  
  52.                     result.writeToParcel(reply, 0);  
  53.                 } else {  
  54.                     reply.writeInt(0);  
  55.                 }  
  56.   
  57.                 return true;  
  58.             }  
  59.             case TRANSACTION_setValue: {  
  60.                 data.enforceInterface(DESCRIPTOR);  
  61.                   
  62.                 int val = data.readInt();  
  63.                 setValue(val);  
  64.                   
  65.                 reply.writeNoException();  
  66.                   
  67.                 return true;  
  68.             }  
  69.             }  
  70.   
  71.             return super.onTransact(code, data, reply, flags);  
  72.         }  
  73.   
  74.         private static class Proxy implements IMemoryService {  
  75.             private IBinder mRemote;  
  76.   
  77.             Proxy(IBinder remote) {  
  78.                 mRemote = remote;  
  79.             }  
  80.   
  81.             public IBinder asBinder() {  
  82.                 return mRemote;  
  83.             }  
  84.   
  85.             public String getInterfaceDescriptor() {  
  86.                 return DESCRIPTOR;  
  87.             }  
  88.   
  89.             public ParcelFileDescriptor getFileDescriptor() throws RemoteException {  
  90.                 Parcel data = Parcel.obtain();  
  91.                 Parcel reply = Parcel.obtain();  
  92.   
  93.                 ParcelFileDescriptor result;  
  94.       
  95.                 try {  
  96.                     data.writeInterfaceToken(DESCRIPTOR);  
  97.   
  98.                     mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);  
  99.           
  100.                     reply.readException();  
  101.                     if (0 != reply.readInt()) {  
  102.                         result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);  
  103.                     } else {  
  104.                         result = null;  
  105.                     }  
  106.                 } finally {  
  107.                     reply.recycle();  
  108.                     data.recycle();  
  109.                 }  
  110.       
  111.                 return result;  
  112.             }  
  113.   
  114.             public void setValue(int val) throws RemoteException {  
  115.                 Parcel data = Parcel.obtain();  
  116.                 Parcel reply = Parcel.obtain();  
  117.   
  118.                 try {  
  119.                     data.writeInterfaceToken(DESCRIPTOR);  
  120.                     data.writeInt(val);  
  121.   
  122.                     mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);  
  123.                       
  124.                     reply.readException();  
  125.                 } finally {  
  126.                     reply.recycle();  
  127.                     data.recycle();  
  128.                 }  
  129.             }  
  130.         }  
  131.   
  132.         static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;  
  133.         static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;  
  134.   
  135.     }  
  136.   
  137.     public ParcelFileDescriptor getFileDescriptor() throws RemoteException;  
  138.     public void setValue(int val) throws RemoteException;  
  139. }  
  1. package shy.luo.ashmem;  
  2.   
  3. import android.util.Log;  
  4. import android.os.IInterface;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7. import android.os.Parcel;  
  8. import android.os.ParcelFileDescriptor;  
  9. import android.os.RemoteException;  
  10.   
  11. public interface IMemoryService extends IInterface {  
  12.     public static abstract class Stub extends Binder implements IMemoryService {  
  13.         private static final String DESCRIPTOR = "shy.luo.ashmem.IMemoryService";  
  14.   
  15.         public Stub() {  
  16.             attachInterface(this, DESCRIPTOR);  
  17.         }  
  18.   
  19.         public static IMemoryService asInterface(IBinder obj) {  
  20.             if (obj == null) {  
  21.                 return null;  
  22.             }  
  23.   
  24.             IInterface iin = (IInterface)obj.queryLocalInterface(DESCRIPTOR);  
  25.             if (iin != null && iin instanceof IMemoryService) {  
  26.                 return (IMemoryService)iin;  
  27.             }  
  28.   
  29.             return new IMemoryService.Stub.Proxy(obj);  
  30.         }  
  31.   
  32.         public IBinder asBinder() {  
  33.             return this;  
  34.         }  
  35.   
  36.         @Override   
  37.         public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {  
  38.             switch (code) {  
  39.             case INTERFACE_TRANSACTION: {  
  40.                 reply.writeString(DESCRIPTOR);  
  41.                 return true;  
  42.             }  
  43.             case TRANSACTION_getFileDescriptor: {  
  44.                 data.enforceInterface(DESCRIPTOR);  
  45.                   
  46.                 ParcelFileDescriptor result = this.getFileDescriptor();  
  47.                   
  48.                 reply.writeNoException();  
  49.                   
  50.                 if (result != null) {  
  51.                     reply.writeInt(1);  
  52.                     result.writeToParcel(reply, 0);  
  53.                 } else {  
  54.                     reply.writeInt(0);  
  55.                 }  
  56.   
  57.                 return true;  
  58.             }  
  59.             case TRANSACTION_setValue: {  
  60.                 data.enforceInterface(DESCRIPTOR);  
  61.                   
  62.                 int val = data.readInt();  
  63.                 setValue(val);  
  64.                   
  65.                 reply.writeNoException();  
  66.                   
  67.                 return true;  
  68.             }  
  69.             }  
  70.   
  71.             return super.onTransact(code, data, reply, flags);  
  72.         }  
  73.   
  74.         private static class Proxy implements IMemoryService {  
  75.             private IBinder mRemote;  
  76.   
  77.             Proxy(IBinder remote) {  
  78.                 mRemote = remote;  
  79.             }  
  80.   
  81.             public IBinder asBinder() {  
  82.                 return mRemote;  
  83.             }  
  84.   
  85.             public String getInterfaceDescriptor() {  
  86.                 return DESCRIPTOR;  
  87.             }  
  88.   
  89.             public ParcelFileDescriptor getFileDescriptor() throws RemoteException {  
  90.                 Parcel data = Parcel.obtain();  
  91.                 Parcel reply = Parcel.obtain();  
  92.   
  93.                 ParcelFileDescriptor result;  
  94.       
  95.                 try {  
  96.                     data.writeInterfaceToken(DESCRIPTOR);  
  97.   
  98.                     mRemote.transact(Stub.TRANSACTION_getFileDescriptor, data, reply, 0);  
  99.           
  100.                     reply.readException();  
  101.                     if (0 != reply.readInt()) {  
  102.                         result = ParcelFileDescriptor.CREATOR.createFromParcel(reply);  
  103.                     } else {  
  104.                         result = null;  
  105.                     }  
  106.                 } finally {  
  107.                     reply.recycle();  
  108.                     data.recycle();  
  109.                 }  
  110.       
  111.                 return result;  
  112.             }  
  113.   
  114.             public void setValue(int val) throws RemoteException {  
  115.                 Parcel data = Parcel.obtain();  
  116.                 Parcel reply = Parcel.obtain();  
  117.   
  118.                 try {  
  119.                     data.writeInterfaceToken(DESCRIPTOR);  
  120.                     data.writeInt(val);  
  121.   
  122.                     mRemote.transact(Stub.TRANSACTION_setValue, data, reply, 0);  
  123.                       
  124.                     reply.readException();  
  125.                 } finally {  
  126.                     reply.recycle();  
  127.                     data.recycle();  
  128.                 }  
  129.             }  
  130.         }  
  131.   
  132.         static final int TRANSACTION_getFileDescriptor = IBinder.FIRST_CALL_TRANSACTION + 0;  
  133.         static final int TRANSACTION_setValue = IBinder.FIRST_CALL_TRANSACTION + 1;  
  134.   
  135.     }  
  136.   
  137.     public ParcelFileDescriptor getFileDescriptor() throws RemoteException;  
  138.     public void setValue(int val) throws RemoteException;  
  139. }  
        這裡主要是定義了IMemoryService介面,它裡面有兩個呼叫介面:

  1. public ParcelFileDescriptor getFileDescriptor() throws RemoteException;  
  2. public void setValue(int val) throws RemoteException;  
  1. public ParcelFileDescriptor getFileDescriptor() throws RemoteException;  
  2. public void setValue(int val) throws RemoteException;  
        同時,還分別定義了用於Server端實現的IMemoryService.Stub基類和用於Client端使用的代理IMemoryService.Stub.Proxy類。關於Binder程式間通訊機制在應用程式框架層的Java介面定義,請參考前面Android系統程式間通訊Binder機制在應用程式框架層的Java介面原始碼分析一文。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-747972/,如需轉載,請註明出處,否則將追究法律責任。

相關文章