javauser71 javauser71 - 17 days ago 5
Android Question

How to access 'Activity' from a Service class via Intent?


I am new to Android programming - so I do not have very clear understanding of the 'Context' and the 'Intent'.


I want to know is there a way to access Activity from a Service class?
i.e. Let's say I have 2 classes - one extends from "Activity" and other extends from "Service" and I have created an intent in my Activity class to initiate the service.

Or, how to access the 'Service' class instance from my 'Activity' class - because in such workflow Service class is not directly instantiated by my Activity-code.

public class MainActivity extends Activity {
.
.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startService(new Intent(this, CommunicationService.class));
.
.
}


public class CommunicationService extends Service implements ..... {
.
.
@Override
public int onStartCommand(final Intent intent, int flags, final int startId) {
super.onStartCommand(intent, flags, startId);
....
}

}

Answer

You can use bindService(Intent intent, ServiceConnection conn, int flags) instead of startService to initiate the service. And the conn will be a inner class just like:

private ServiceConnection conn = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mMyService = ((CommunicationService.MyBinder) service).getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};

mMyService is the instance of your CommunicationService.

In your CommunicationService, just override:

public IBinder onBind(Intent intent) {
    return new MyBinder();
}

and the following class in your CommunicationService:

public class MyBinder extends Binder {
    public CommunicationService getService() {
        return CommunicationService.this;
    }
}

So you can use mMyService to access any public methods and fields in your activity.

In addition, you can use callback interface to access activity in your service.

First write a interface like:

public interface OnChangeListener {
    public void onChanged(int progress);
}

and in your service, please add a public method:

public void setOnChangeListener(OnChangeListener onChangeListener) {
    this.mOnChangeListener = onChangeListener;
}

you can use the onChanged in your service anywhere, and the implement just in your activity:

    public void onServiceConnected(ComponentName name, IBinder service) {
        mMyService = ((CommunicationService.MyBinder) service).getService();
        mMyService.setOnChangeListener(new OnChangeListener() {
            @Override
            public void onChanged(int progress) {
                // anything you want to do, for example update the progressBar
                // mProgressBar.setProgress(progress);
            }
        });
    }

ps: bindService will be like this:

this.bindService(intent, conn, Context.BIND_AUTO_CREATE);

and do not forget

protected void onDestroy() {
    this.unbindService(conn);
    super.onDestroy();
}

Hope it helps.

Comments