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

http://blog.csdn.net/citycity222/article/details/6897449

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,源码如下

 

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

 
Java代码  
[javascript] view plain copy
  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. }    

 

 

步骤二:编写服务的实现类MediaPlaybackService

Java代码  
[javascript] view plain copy
  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. }    

 

 

步骤三:编写一个消费这个服务的Activity:MediaPlaybackActivity:(除此之外还有其他类)

Java代码  
[javascript] view plain copy
  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.iteye.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是两者均可设置。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值