Android: pass parameter to Service from Activity

2019-01-22 13:43发布

I'm binding to Service by this way:

Activity class:

ListenLocationService mService;
@Override
public void onCreate(Bundle savedInstanceState) {
        ...
        Intent intent = new Intent(this, ListenLocationService.class);
        intent.putExtra("From", "Main");
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        ...
}

private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className,
                IBinder service) {
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();         
        }

        public void onServiceDisconnected(ComponentName arg0) {
        }
    };

This is onBind method of my Service:

@Override
public IBinder onBind(Intent intent) {
    Bundle extras = intent.getExtras(); 
    if(extras == null)
        Log.d("Service","null");
    else
    {
        Log.d("Service","not null");
        String from = (String) extras.get("From");
        if(from.equalsIgnoreCase("Main"))
            StartListenLocation();
    }
    return mBinder;
}

So I have "null" in LogCat - bundle is null in spite of I made intent.putExtra before bindService

In general Service works fine. However I need to call StartListenLocation(); only from main activity of application (I decide to do this by sending a flag).

How can I send a data to service?Or maybe there's another way to check what activity launched onBind?

3条回答
女痞
2楼-- · 2019-01-22 14:09

You can pass the parameter in this simple way:-

Intent serviceIntent = new Intent(this,ListenLocationService.class); 
   serviceIntent.putExtra("From", "Main");
   startService(serviceIntent);

and get the parameter in onStart method of your service class

    @Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
     Bundle extras = intent.getExtras(); 
if(extras == null)
    Log.d("Service","null");
else
{
    Log.d("Service","not null");
    String from = (String) extras.get("From");
    if(from.equalsIgnoreCase("Main"))
        StartListenLocation();
}

}

Enjoy :)

查看更多
乱世女痞
3楼-- · 2019-01-22 14:09

According to this session http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html

One way of sending data to a service is by using a database containing of columns pid(process id),data,status where the status can be READ , READY , BINDING and so on , when the service is load it reads the table which is filled by the calling activity and can be deleted when finished , the other way indicated is AIDL as indicated in the previous answer , choose according to your application.

查看更多
贪生不怕死
4楼-- · 2019-01-22 14:23

1 Create a interface that declare all method signature that you want to call from a Activity:

public interface ILocationService {
  public void StartListenLocation(Location location);
}

2 Make your binder implements ILocaionService and define the actual method body:

public class MyBinder extends Binder implements ILocationService {
  ... ...

  public void StartListenLocation(Location location) {
    // implement your method properly
  }

  ... ...
}

3 In activity that bind to the service, reference your binder by the interface:

... ...

ILocationService mService; // communication is handled via Binder not the actual service class.

private ServiceConnection mConnection = new ServiceConnection() {

  public void onServiceConnected(ComponentName className, IBinder service) {
    mService = (ILocationService) service;     
  }

  ... ...
};

... ...

// At some point if you need call service method with parameter:
Location location = new Location();
mService.StartListenLocation(location);

All communications (i.e. method call to your Service) should be handled and performed via the binder class initialize and return in ServiceConnection.onServiceConnected(), not the actual service class (binder.getService() is unnecessary). This is how bind service communication designed to work in the API.

Note that bindService() is an asynchronous call. There will be a lag after you call bindService() and before ServiceConnection.onServiceConnected() callback get involved by system. So the best place to perform service method is immediately after mService get initialized in ServiceConnection.onServiceConnected() method.

Hope this helps.

查看更多
登录 后发表回答