Calling Activity Class Method from Service Class

Calling activity class method from Service class

Define an interface your Service will use to communicate events:

public interface ServiceCallbacks {
void doSomething();
}

Write your Service class. Your Activity will bind to this service, so follow the sample shown here. In addition, we will add a method to set the ServiceCallbacks.

public class MyService extends Service {
// Binder given to clients
private final IBinder binder = new LocalBinder();
// Registered callbacks
private ServiceCallbacks serviceCallbacks;


// Class used for the client Binder.
public class LocalBinder extends Binder {
MyService getService() {
// Return this instance of MyService so clients can call public methods
return MyService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return binder;
}

public void setCallbacks(ServiceCallbacks callbacks) {
serviceCallbacks = callbacks;
}
}

Write your Activity class following the same guide, but also make it implement your ServiceCallbacks interface. When you bind/unbind from the Service, you will register/unregister it by calling setCallbacks on the Service.

public class MyActivity extends Activity implements ServiceCallbacks {
private MyService myService;
private boolean bound = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
}

@Override
protected void onStart() {
super.onStart();
// bind to Service
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from service
if (bound) {
myService.setCallbacks(null); // unregister
unbindService(serviceConnection);
bound = false;
}
}

/** Callbacks for service binding, passed to bindService() */
private ServiceConnection serviceConnection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// cast the IBinder and get MyService instance
LocalBinder binder = (LocalBinder) service;
myService = binder.getService();
bound = true;
myService.setCallbacks(MyActivity.this); // register
}

@Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};

/* Defined by ServiceCallbacks interface */
@Override
public void doSomething() {
...
}
}

Now when your service wants to communicate back to the activity, just call one of the interface methods from earlier. Inside your service:

if (serviceCallbacks != null) { 
serviceCallbacks.doSomething();
}

How to call a method in activity from a service

I would register a BroadcastReceiver in the Activity and send an Intent to it from the service.
See this tutorial: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html
It might look a bit long but you'll want to learn how to use those anyway ;)

how to cal the activity method from the service

Its a good question, probably been asked many times before but one that stumped me to begin with.

You have several options, the easiest of which is to register a listener with your activity, but this would require you to implement onBind(Intent) so you can connect from the activity to the service so you can register the listener.

The following example shows you how to do this, once you have registered the activity as a listener with setServiceClient(ExampleServiceClient) the service can then invoke the method exampleServiceClientMethod() on the activity.

You will notice I use a WeakReference when registering the client, always make sure you check to see you still have the reference when invoking any methods you add to ExampleServiceClient.

public class ExampleService extends Service {

public interface ExampleServiceClient {
void exampleServiceClientMethod();
}

private WeakReference<ExampleServiceClient> mClient;

public void setServiceClient(ExampleServiceClient client) {
if(client == null) {
mClient = null;
return;
}

mClient = new WeakReference<ExampleServiceClient>(client);
}

public class ExampleBinder extends Binder {
ExampleService getService() {
return ExampleService.this;
}
}

private IBinder mBinder = new ExampleBinder();

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}

Your activity:

public class ExampleServiceActivity extends Activity implements ExampleServiceClient {

private ExampleServiceConnection mServiceConnection = new ExampleServiceConnection();
private ExampleService mService = null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

bindService(new Intent(this, ExampleService.class), mServiceConnection, BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
super.onDestroy();

unbindService(mServiceConnection);
}


class ExampleServiceConnection implements ServiceConnection {

public void onServiceConnected(ComponentName name, IBinder service) {
mService = ((ExampleBinder)service).getService();

mService.setServiceClient(ExampleServiceActivity.this);
}

public void onServiceDisconnected(ComponentName name) {
mService.setServiceClient(null);
mService = null;

}
}


public void exampleServiceClientMethod() {
// TODO Auto-generated method stub
}
}

Hope that helps.

Android call method in Service from Activity

A simpke way is to send an intent from Activity and handle it in onStartCommand() method of Service. Don't forget to supply intent with right action/extras & check that in onStartCommand()

EDIT:

Activity:

Add a private class:

    private class CustomReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_CUSTOM_ACTION)) {
doCustomAction();
}
}
}

Add a private field:

private CustomReceiver mCustomReceiver;

In onCreate() method:

mCustomReceiver = new CustomReceiver();

In onResume() or other lifecycle method:

IntentFilter filter = new IntentFilter(ACTION_CUSTOM_ACTION);   
registerReceiver(mCustomReceiver , filter);

In onPause() or other paired(to previous step) lifecycle method

unregisterReceiver(mCustomReceiver );

In activity whenever you wish to call use Service methods:

startService(new Intent(SOME_ACTION));

In Service:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

if (intent == null) {
return START_STICKY;
}

String action = intent.getAction();

if (action == null) {
return START_STICKY;
} else if (action.equals(SOME_ACTION)) {
invokeSomeServiceMethod();// here you invoke service method
}

return START_STICKY;
}

Note, that START_STICKY may be not the best choice for you, read about modes in documentation.

Then, when you want to notify activity that you've finished, call:

startActivity(ACTION_CUSTOM_ACTION);

This will trigger broadcast reciever where you can handle finish event.

Seems that that's a lot of code, but really nothing difficult.



Related Topics



Leave a reply



Submit