在android平台中,一个进程通常不能访问其他进程中的内存区域的。但是,我们可以使用IDL语言来把对象伪装成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。

如果想在应用程序中调用其他进程中的Service,则需要用到AIDL,AIDL(android接口描述语言)是一种IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
 

 

使用AIDL的方法如下:
1.首先生成一个IMusicService.aidl的服务接口,Android会自动生成一个 Stub类,这个类继承了BInder类,同时继承了IMusicService这个接口,还可以看到其中包含了一个Proxy代理类,以实现远程代理。(aidl和Stub类如下所示)
 
 
  
  1. /**  
  2.  * IMusicService.aidl  
  3.  * com.androidtest.service.mediaplayer  
  4.  *  
  5.  * Function: TODO  
  6.  *  
  7.  *   ver     date           author  
  8.  * ──────────────────────────────────  
  9.  *           2011-5-19      Leon  
  10.  *  
  11.  * Copyright (c) 2011, TNT All Rights Reserved.  
  12. */  
  13.    
  14. package com.androidtest.service.mediaplayer;  
  15. /**  
  16.  * ClassName:IMusicService  
  17.  * Function: TODO ADD FUNCTION  
  18.  * Reason:   TODO ADD REASON  
  19.  *  
  20.  * @author   Leon  
  21.  * @version  
  22.  * @since    Ver 1.1  
  23.  * @Date     2011-5-19  
  24.  */  
  25.    
  26. interface IMusicService{  
  27.     void play();  
  28.     void pause();  
  29.     void stop();  
  30. }  
  31.    
  32. /*  
  33.  * This file is auto-generated.  DO NOT MODIFY.  
  34.  * Original file: D:\\Backup\\�ҵ��ĵ�\\Dropbox\\investment\\A8\\workspace\\androidtest\\src\\com\\androidtest\\service\\mediaplayer\\IMusicService.aidl  
  35.  */  
  36. package com.androidtest.service.mediaplayer;  
  37.    
  38. /**  
  39.  * ClassName:IMusicService Function: TODO ADD FUNCTION Reason: TODO ADD REASON  
  40.  *  
  41.  * @author Leon  
  42.  * @version  
  43.  * @since Ver 1.1  
  44.  * @Date 2011-5-19  
  45.  */  
  46. public interface IMusicService extends android.os.IInterface {  
  47.     /** Local-side IPC implementation stub class. */  
  48.     public static abstract class Stub extends android.os.Binder implements  
  49.             com.androidtest.service.mediaplayer.IMusicService {  
  50.         private static final java.lang.String DESCRIPTOR = "com.androidtest.service.mediaplayer.IMusicService";  
  51.    
  52.         /** Construct the stub at attach it to the interface. */  
  53.         public Stub() {  
  54.             this.attachInterface(this, DESCRIPTOR);  
  55.         }  
  56.    
  57.         /**  
  58.          * Cast an IBinder object into an  
  59.          * com.androidtest.service.mediaplayer.IMusicService interface,  
  60.          * generating a proxy if needed.  
  61.          */  
  62.         public static com.androidtest.service.mediaplayer.IMusicService asInterface(  
  63.                 android.os.IBinder obj) {  
  64.             if ((obj == null)) {  
  65.                 return null;  
  66.             }  
  67.             android.os.IInterface iin = (android.os.IInterface) obj  
  68.                     .queryLocalInterface(DESCRIPTOR);  
  69.             if (((iin != null) && (iin instanceof com.androidtest.service.mediaplayer.IMusicService))) {  
  70.                 return ((com.androidtest.service.mediaplayer.IMusicService) iin);  
  71.             }  
  72.             return new com.androidtest.service.mediaplayer.IMusicService.Stub.Proxy(  
  73.                     obj);  
  74.         }  
  75.    
  76.         public android.os.IBinder asBinder() {  
  77.             return this;  
  78.         }  
  79.    
  80.         @Override  
  81.         public boolean onTransact(int code, android.os.Parcel data,  
  82.                 android.os.Parcel reply, int flags)  
  83.                 throws android.os.RemoteException {  
  84.             switch (code) {  
  85.             case INTERFACE_TRANSACTION: {  
  86.                 reply.writeString(DESCRIPTOR);  
  87.                 return true;  
  88.             }  
  89.             case TRANSACTION_play: {  
  90.                 data.enforceInterface(DESCRIPTOR);  
  91.                 this.play();  
  92.                 reply.writeNoException();  
  93.                 return true;  
  94.             }  
  95.             case TRANSACTION_pause: {  
  96.                 data.enforceInterface(DESCRIPTOR);  
  97.                 this.pause();  
  98.                 reply.writeNoException();  
  99.                 return true;  
  100.             }  
  101.             case TRANSACTION_stop: {  
  102.                 data.enforceInterface(DESCRIPTOR);  
  103.                 this.stop();  
  104.                 reply.writeNoException();  
  105.                 return true;  
  106.             }  
  107.             }  
  108.             return super.onTransact(code, data, reply, flags);  
  109.         }  
  110.    
  111.         private static class Proxy implements  
  112.                 com.androidtest.service.mediaplayer.IMusicService {  
  113.             private android.os.IBinder mRemote;  
  114.    
  115.             Proxy(android.os.IBinder remote) {  
  116.                 mRemote = remote;  
  117.             }  
  118.    
  119.             public android.os.IBinder asBinder() {  
  120.                 return mRemote;  
  121.             }  
  122.    
  123.             public java.lang.String getInterfaceDescriptor() {  
  124.                 return DESCRIPTOR;  
  125.             }  
  126.    
  127.             public void play() throws android.os.RemoteException {  
  128.                 android.os.Parcel _data = android.os.Parcel.obtain();  
  129.                 android.os.Parcel _reply = android.os.Parcel.obtain();  
  130.                 try {  
  131.                     _data.writeInterfaceToken(DESCRIPTOR);  
  132.                     mRemote.transact(Stub.TRANSACTION_play, _data, _reply, 0);  
  133.                     _reply.readException();  
  134.                 } finally {  
  135.                     _reply.recycle();  
  136.                     _data.recycle();  
  137.                 }  
  138.             }  
  139.    
  140.             public void pause() throws android.os.RemoteException {  
  141.                 android.os.Parcel _data = android.os.Parcel.obtain();  
  142.                 android.os.Parcel _reply = android.os.Parcel.obtain();  
  143.                 try {  
  144.                     _data.writeInterfaceToken(DESCRIPTOR);  
  145.                     mRemote.transact(Stub.TRANSACTION_pause, _data, _reply, 0);  
  146.                     _reply.readException();  
  147.                 } finally {  
  148.                     _reply.recycle();  
  149.                     _data.recycle();  
  150.                 }  
  151.             }  
  152.    
  153.             public void stop() throws android.os.RemoteException {  
  154.                 android.os.Parcel _data = android.os.Parcel.obtain();  
  155.                 android.os.Parcel _reply = android.os.Parcel.obtain();  
  156.                 try {  
  157.                     _data.writeInterfaceToken(DESCRIPTOR);  
  158.                     mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0);  
  159.                     _reply.readException();  
  160.                 } finally {  
  161.                     _reply.recycle();  
  162.                     _data.recycle();  
  163.                 }  
  164.             }  
  165.         }  
  166.    
  167.         static final int TRANSACTION_play = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);  
  168.         static final int TRANSACTION_pause = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);  
  169.         static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);  
  170.     }  
  171.    
  172.     public void play() throws android.os.RemoteException;  
  173.    
  174.     public void pause() throws android.os.RemoteException;  
  175.    
  176.     public void stop() throws android.os.RemoteException;  

2. 在MyRemoteBinder需要继承这个Stub类,对播放器的控制写在这个Binder类中

?[Copy to clipboard] Download zuiniuwang.java
 
 
   
  1. /**  
  2.  * MyRemoteBinder.java  
  3.  * com.androidtest.service.mediaplayer  
  4.  *  
  5.  * Function: TODO  
  6.  *  
  7.  *   ver     date           author  
  8.  * ──────────────────────────────────  
  9.  *           2011-5-19      Leon  
  10.  *  
  11.  * Copyright (c) 2011, TNT All Rights Reserved.  
  12. */  
  13.    
  14. package com.androidtest.service.mediaplayer;  
  15.    
  16. import android.media.MediaPlayer;  
  17. import android.os.Binder;  
  18. import android.os.RemoteException;  
  19.    
  20. /**  
  21.  * ClassName:MyRemoteBinder  
  22.  * Function: TODO ADD FUNCTION  
  23.  * Reason:   TODO ADD REASON  
  24.  *  
  25.  * @author   Leon  
  26.  * @version  
  27.  * @since    Ver 1.1  
  28.  * @Date     2011-5-19  
  29.  */  
  30. public class MyRemoteBinder extends IMusicService.Stub{  
  31.    
  32.     public  MyRemoteBinder(MediaPlayer mediaPlayer){  
  33.         MyMediaController.mediaPlayer=mediaPlayer ;  
  34.     };  
  35.    
  36.     @Override  
  37.     public void play() throws RemoteException {  
  38.    
  39.         // TODO Auto-generated method stub  
  40.         MyMediaController.play.execute();  
  41.    
  42.     }  
  43.    
  44.     @Override  
  45.     public void pause() throws RemoteException {  
  46.    
  47.         // TODO Auto-generated method stub  
  48.         MyMediaController.pause.execute();  
  49.    
  50.     }  
  51.    
  52.     @Override  
  53.     public void stop() throws RemoteException {  
  54.    
  55.         // TODO Auto-generated method stub  
  56.         MyMediaController.stop.execute();  
  57.    
  58.     };   
  59.    

3. 在Activity中得到Binder的方式,是通过Stub类的IMusicService.Stub.asInterface(binder)方法

 
 
  
  1. private ServiceConnection myServiceConnection = new ServiceConnection() {  
  2.  
  3.     @Override  
  4.     public void onServiceConnected(ComponentName name, IBinder binder) {  
  5.         musicServiceInterface = IMusicService.Stub.asInterface(binder);  
  6.         Log.d(TAG, " onServiceConnected");  
  7.     }  
  8.  
  9.     @Override  
  10.     public void onServiceDisconnected(ComponentName name) {  
  11.         musicServiceInterface = null;  
  12.         Log.d(TAG, " onServiceDisconnected");  
  13.     }  
  14.  
  15. };