2015年4月1日 星期三

[Android] About Service - how to pass data to Service

We may need to pass some information to Service sometimes.
For example, the file to play, the control commands, and so on.

There have few ways we can use.
First method is to use the way of passing data between Intent.
When we start the Service, we can include the data at the same time.
Intent i = new Intent(this,myServiceClass.class);
i.putExtra("DATA_KEY1","my data");
i.putExtra("DATA_KEY2",1234);
startService(i);
In the case above, we put string "my data" and number 1234 in the intent.

In the Service, how can it retrieve these data?
@Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  String sData1=Intent.getStringExtra("DATA_KEY1");
  int iData2=Intent.getIntExtra("DATA_KEY2",0);
  mServiceThread = new ServiceThread();
  mServiceThread.start();
     return  START_STICKY ; 
 }   
We can get the passed data in onStartCommand().
That is, sData1 will be "my data" and iData2 will be 1234.

We can call startService() repeatedly and pass the desired data.
Once we call startService(), the function onStartCommand() will be executed accordingly.
Note that in the above case, onStartCommand() will run new ServiceThread() and mServiceThread.start().
We need to prevent them being executed duplicatedly if we call startService() few times.

Another common way is to use the bindService mechanism.
public class myService  extends Service {
 private ServiceThread mServiceThread; 
 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return new myServiceLocalBinder();
 }
 
 @Override
 public void onCreate() {
 // TODO Auto-generated method stub
 super.onCreate();
 }
  
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  mServiceThread = new ServiceThread();
  mServiceThread.start();
     return  START_STICKY ; 
 }     
  
 public class myServiceLocalBinder extends Binder {  
  myService getService() {  
            // Return this instance of LocalService so clients can call public methods  
            return myService.this;  
        }     
    }

 public void SendData2Service(String s, int i)
 {
   //your action here
 }
  
  
 @Override
 public void onDestroy() {
  Log.d(TAG,"onDestroy()");
  if (mServiceThread != null)
   mServiceThread.interrupt();
 }
  
 private class ServiceThread extends Thread {
  @Override
  public void run() {
   super.run();
   //your action here
  }
 } 
}
Then we need to modify the way how we start the Service:
myServiceClass myService=null; 

private ServiceConnection sMyServiceConnection = new ServiceConnection() {    
 @Override  
 public void onServiceDisconnected(ComponentName name) {  
 }    
 
 @Override
 public void onServiceConnected(ComponentName name, IBinder service) {
  myService = ((myServiceClass.myServiceLocalBinder) service).getService();  
 }  
};  

 public void StartMyService() {
   Intent i = new Intent(this, myService.class);  
   bindService(i, sMyServiceConnection , BIND_AUTO_CREATE);
   startService(i);
 }
 
 public void StopMyService(){
  Intent i = new Intent(this,myServiceClass.class);
 try{
     unbindService(sMyServiceConnection);
     stopService(i);
  } catch (IllegalArgumentException e){              
 } 
 }
When we want to pass the data to Service, we can use myService.SendData2Service().

沒有留言:

張貼留言