I've got a service meant to sometimes run in the background - started with startService(). What is the advantage of binding to this service so as to get/set its variables, instead of - controversial, I know, but still - just accessing its public variables directly (e.g. myVar = mainService.itsVar), or using SharedPrefs to set and get the values? Especially, what is the fastest, in terms of performance, based on the fact that the get interval would be roughly 3 seconds?
Advantage - You can access variables and run methods directly. Disadvantage - allot of cross thread headache, not to mention unresolved crashes on google developer console.
How to do it correctly, I will give example of a foreground service, if it can be background then change only how to start it:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContext.startForegroundService(startIntent)
} else {
mContext.startService(startIntent);
}
In the service you need to implement all binding methods:
private IBinder mBinder = new MyBinder();
public MainService() {
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
return true;
}
public class MyBinder extends Binder {
public MainService getService() {
return com.xxx.xxx.MainService.this;
}
}
In the activity you need to listen to connection:
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mBoundService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "connecting");
MainService.MyBinder myBinder = (MainService.MyBinder) service;
mBoundService = myBinder.getService();
mShouldUnbind.set(true);
}
};
If other activity or alarm can start your service you will need to check every second or so if the service was started by other and bind to it. Important - service run on the same thread like the main/GUI thread - so if you have time consumption actions like camera or uploading - you will need to start a background thread. back communication can be made by calling the GUI/main thread. on foreground service like mine - you need also to manage notifications otherwise the o.s. will kill the service after 5 seconds.
Code example:
if (mShouldUnbind.get() && mBoundService != null)
val = mBoundService.getTimestamp();
Edit I: advantage: I have a camera foreground service - I can set zoom values directly from the GUI thread since I have a handle to the service. the camera is running on the background thread in the service, but, since the preview is being drawn 30 times pro seconds - the zoom is set without any lag. you will never manage to do it in any other way.