Android Serviceの思考(4)


Androidプラットフォームでは、1つのプロセスは通常、他のプロセスのメモリ領域にアクセスできません.しかし、IDL言語を使用して、オブジェクトをオペレーティングシステムが理解できる簡単な形式に偽装し、オブジェクトが境界を越えてアクセスするように偽装することができます.
アプリケーションで他のプロセスのサービスを呼び出す場合は、AIDLが必要です.AIDL(androidインタフェース記述言語)は、1つのandroidデバイス上で実行される2つのプロセスを内部通信プロセスでインタラクティブにするためのコードを生成するIDL言語です.1つのプロセス(たとえば、1つのActivity)で別のプロセス(たとえば、1つのService)のオブジェクトにアクセスする方法が必要な場合は、AIDLを使用してこのようなコードを生成して、さまざまなパラメータを偽装して渡すことができます.
 
 
AIDLを使用する方法は次のとおりです.
1.まずIMusicServicesを生成する.aidlのサービスインタフェース、Androidは自動的に1つのStubクラスを生成して、このクラスはBInderクラスを継承して、同時にIMusicServiceというインタフェースを継承して、その中に1つのProxyエージェントクラスを含んで、遠隔エージェントを実現することを見ることができます.(aidlとStubクラスは以下の通り)
?[Copy to clipboard]
Download zuiniuwang.java
 
 
   
   
   
   
  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クラスのIMusicServicesによる.Stub.asInterface(binder)メソッド
?[Copy to clipboard]
Download zuiniuwang.java
 
 
   
   
   
   
  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. };