2010年11月2日 星期二

Android Service-幾種應用範例(二)

一.實作要點

1.說明
Service提供兩種的使用方式,如果Client只是透過startService去執行Service的功能,只是把要做的功能寫在onStartCommand內即可,若是Client透過bindService來執行Service,就需要在Service內產生Ibinder物件,讓onBind可以把binder物件傳給Client,讓Client可以由取到的binder物件再取到Service物件,然後就可以呼叫Service上提供的method

2.Activity(使用Service的Client)
1.extends Activity物件
2.實做ServiceConnection(需要bindService時使用)
  實做並產生一個connection instance,在connection內
  override其onServiceConnected(ComponentName className, IBinder service)
  與onServiceDisconnected(ComponentName className)

3.onServiceConnected被自動呼叫(需要bindService時使用)
  在與Service連線成功後,onServiceConnected會被自動呼
  叫並接收到由Service內部onBinder所發送出來的IBinder物件,
  通常會是extends 自Binder
4.取得Service物件(需要bindService時使用)
  將取得的Binder物件呼叫其Class內定義的方法(如getService)
  來取得Service物件,如Service(binder.getService())
5.利用取得的Service呼叫執行中Service上的public method

3.Service(提供服務的元件)
1.extends Service物件
2.設計binder class extends Binder(需要bindService時使用)
  設計一個內部Binder Clas並產生binder instance,在class內
  建立getService function,可以透過這binder取得所在的service
3.overrider onBinder function(需要bindService時使用)
  將已建立的binder instance傳出去
4.override onStartCommand(需要用startService時使用)
  若只用startService啟動Service,只需要override這
  function即可

二.Sample:LocalService 使用startService

1.說明
透過startService呼叫Service會執行Service內部的onStartCommand(),所以把要執行的工作放在override的onStartCommand()內

2.Activity
Intent intent = new Intent(this, MusicService.class);
intent.putExtra("songPath","sdcard/mp3/mySong.mp3");
this.startService(intent);
3.Service
@Override
public void onCreate() {    
    super.onCreate();
    mp=new MediaPlayer();    
}
@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    String songPath=intent.getExtras().getString("songPath");
    try{
        mp.setDataSource(_path);
        mp.prepare();
        mp.start();
    }catch(Exception e){};
}

三.Sample:LocalService 使用bindService

1.說明
透過bind方式要執行Service上的功能,是透過建立連線物件後,再直接對Service做操作,要做的工作就寫成Service內public method 讓人呼叫執行

2.Activity
private MusicService mService;
@Override
public void onCreate(Bundle _state){
    doBindService()
}
private void doBindService(){
    Intent intent = new Intent(MyActivity.this, MusicService.class);
    bindService(intent, connc,Context.BIND_AUTO_CREATE);
}
private ServiceConnection connc=new ServiceConnection() {            
    @Override
    public void onServiceDisconnected(ComponentName name) {    
    }
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {        
        mService=((MusicService.LocalBinder)service).getService();        
    }
};

要使用service上的function就可以直接用,如 mService.start(),mService.stop()...等定義在Service內public的方法。若要取得回傳值,只要service內的function有回傳值,直接接收就可以了,例如
String _path=mService.getSongPath();

3.Service
內定義一個內部Binder class可以用來取得service
public class LocalBinder extends Binder {
     MusicService getService() {
        return  MusicService.this;
    }
}
private final IBinder mBinder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {    
    return mBinder;
}

沒有留言: