Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> android播放器(music player)源碼分析1-Service,Binder,ServiceConnection

android播放器(music player)源碼分析1-Service,Binder,ServiceConnection

編輯:Android開發實例

Android SDK 提供了兩種類型的 Service ,用於類似 *nix 守護進程或者 windows 的服務

1. 本地服務 Local Service :用於應用程序內部

2. 遠程服務 Remote Service :用於 android 系統內部的應用程序之間

前者用於實現應用程序自己的一些耗時任務,比如查詢升級信息,並不占用應用程式比如 Activity 所屬線程,而是單開線程後台執行,這樣用戶體驗比較好。

後者可被其他應用程序服用,比如天氣預報服務,其他應用程序不需要再寫這樣的服務,調用已有的即可。

不需要和 Activitye 交互的本地服務

本地服務編寫比較簡單。首先,要創建一個 Service 類,該類繼承 android 的 Service 類。然後在 Activity 中的 onCreate 和 onDestory 中分別執行以下語句開啟服務和停止服務。

this .startService( new Intent( this , ServiceImpl. class ));

this .stopService( new Intent( this , ServiceImpl. class ));

需要和 Activity 交互的遠程服務

上面的示例是通過 startService 和 stopService 啟動關閉服務的。適用於服務和 activity 之間沒有調用交互的情況。如果之間需要傳遞參數或者方法調用。需要使用 bind 和 unbind 方法。

具體做法是,服務類需要增加接口,比如 ServiceInterface ,另外,服務類需要有一個內部類,這樣可以方便訪問外部類的封裝數據,這個內部類需要繼承 Binder 類並實現 ServiceInterface 接口。還有,就是要實現 Service 的 onBind 方法,不能只傳回一個 null 了。

在 android 的 musicplayer 源碼中 MediaPlaybackService 使用了以上的服務方式,針對該源碼進行分析:

首先需要了解進程間通信、需要 AIDL (以及 Binder )

關於 AIDL 的介紹在文檔: docs/guide/developing/tools/aidl.html

關於 IBinder 的介紹在文檔: docs/reference/android/os/IBinder.html

以及 Binder : docs/reference/android/os/Binder.html

manifest 中 Service 的語法,見 docs/guide/topics/manifest /service-element.html

以上轉自 http://blog.csdn.net/saintswordsman/archive/2010/01/05/5130947.aspx

步驟一:建立 aidl 文件

通過 aidl.exe 會在 gen 中生成該 service 類,該類中的成員變量 stub 實現了以下功能:

extends Binder implements ServiceInterface,源碼如下

 

  1. interface IMediaPlaybackService  
  2. {  
  3.     void openfile(String path);  
  4.     void openfileAsync(String path);  
  5.     void open(in int [] list, int position);  
  6.     ...................//接口方法  
  7. }  

 

  1. public interface IMediaPlaybackService extends android.os.IInterface {  
  2.     /**生成binder類 */ 
  3.     public static abstract class Stub extends android.os.Binder implements 
  4.             com.android.mymusic.IMediaPlaybackService {  
  5.         private static final java.lang.String DESCRIPTOR = "com.android.mymusic.IMediaPlaybackService";  
  6.  
  7.         /** Construct the stub at attach it to the interface. */ 
  8.         public Stub() {  
  9.             this.attachInterface(this, DESCRIPTOR);  
  10.         }  
  11.         ...................  
  12.         ...................  
  13.         ...................//binder 方法  
  14.     }  
  15.           
  16.     public void openfile(java.lang.String path)  
  17.             throws android.os.RemoteException;  
  18.         ...................  
  19.     ...................//接口方法  
  20.     ...................  
  21.  
  22. }  
  23.  
  24.  

 

 

步驟二:編寫服務的實現類 MediaPlaybackService

 
  1. public class MediaPlaybackService extends Service {  
  2.  
  3.      ......  
  4.    
  5.      @Override 
  6.     public IBinder onBind(Intent intent) {  
  7.         mDelayedStopHandler.removeCallbacksAndMessages(null);  
  8.         mServiceInUse = true;  
  9.         return mBinder;  
  10.     }  
  11.     private final IMediaPlaybackService.Stub mBinder = new IMediaPlaybackService.Stub()  
  12.     {  
  13.           ...................//實現接口方法  
  14.     };  
  15. }  
  16.  
  17.  

 

 

步驟三:編寫一個消費這個服務的 Activity : MediaPlaybackActivity: (除此之外還有其他類)

 
  1. public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,  
  2.     View.OnTouchListener, View.OnLongClickListener  
  3. {  
  4.     private IMediaPlaybackService mService = null;  
  5.  
  6.     @Override 
  7.     public void onStart() {  
  8.         super.onStart();  
  9.         ...................//其他代碼  
  10.  
  11.         if (false == MusicUtils.bindToService(this, serviecConnection)) {  
  12.             // something went wrong  
  13.         ...................//其他代碼  
  14.         }  
  15.  
  16.     private ServiceConnection serviecConnection = new ServiceConnection() {  
  17.             public void onServiceConnected(ComponentName classname, IBinder obj) {  
  18.                 mService = IMediaPlaybackService.Stub.asInterface(obj);  
  19.                 if (MusicUtils.sService == null) {  
  20.                     MusicUtils.sService = mService;  
  21.                       
  22.                         ...................//其他代碼  
  23.  
  24.                 }  
  25.             }  
  26.             public void onServiceDisconnected(ComponentName classname) {  
  27.             }  
  28.     };  
  29. }  
  30. //MusicUtils類:定義了播放器所需要的操作以及service和Activity之間的相互作用的操作  
  31. public class MusicUtils {  
  32.  
  33.     ...................//其他代碼  
  34.       
  35.     public static boolean bindToService(Context context, ServiceConnection callback) {  
  36.         context.startService(new Intent(context, MediaPlaybackService.class));  
  37.         ServiceBinder sb = new ServiceBinder(callback);  
  38.         sConnectionMap.put(context, sb);  
  39.         return context.bindService((new Intent()).setClass(context,  
  40.                 MediaPlaybackService.class), sb, 0);  
  41.     }  
  42.       
  43.     ...................//其他代碼  
  44.       
  45. }  

 

 

需要注意:

遠程服務往往不只是傳遞 java 基本數據類型。這時需要注意 android 的一些限制和規定:

   以下轉自 http://yangguangfu.javaeye.com/blog/699306

1. android 支持 String 和 CharSequence

2. 如果需要在 aidl 中使用其他 aidl 接口類型,需要 import ,即使是在相同包結構下;

3. android 允許傳遞實現 Parcelable 接口的類,需要 import ;

4.  android 支持集合接口類型 List 和 Map ,但是有一些限制,元素必須是基本型或者上述三種情況,不需要 import 集合接口類,但是需要對元素涉及到的類型 import ;

非基本數據類型,也不是 String 和 CharSequence 類型的,需要有方向指示,包括 in 、 out 和 inout , in 表示由客戶端設置, out 表示由服務端設置, inout 是兩者均可設置。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved