Android Component and Service Talk
This article will give you an idea which can be used for communication between an activity/fragment and a service class. You can find lots of article on this topic but I’ll try to give an idea of all possible ways. Ok so enough talk let me start with it.
Bus architecture :
You can use EventBus from greenrobot.
Using Broadcast Receivers :
Assume we have an Intent service and we want to pass our data to activity then we can use broadcast receivers for communication. Your Service class will look like this:
public class TestIntentService extends IntentService {
public TestIntentService() {
super("TestIntentService");
} @Override
protected void onHandleIntent(@Nullable Intent intent) {
// doSomeWork()
..
..
Intent senderIntent = new Intent();
senderIntent.setAction(ServiceReceivers.SERVICE_ACTION);
senderIntent.putExtra("data","result");
senderIntent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(senderIntent);
}
}
Broadcast Receiver class will look like this :
public class ServiceReceivers extends BroadcastReceiver { public final static String SERVICE_ACTION = "com.example.keerthiacharya.androidjob.receivers";
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive", "onReceive: "+intent.getExtras().getString("data"));
}
}
and inside main activity register receiver
// write this code inside onCreate()
serviceReceivers = new ServiceReceivers();
IntentFilter intentFilter = new IntentFilter(ServiceReceivers.SERVICE_ACTION);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(serviceReceivers,intentFilter);..
..
..// make sure to unRegister it on pause@Override
protected void onPause() {
super.onPause();
unregisterReceiver(serviceReceivers);
}
Using RegisterReceiver
Generic interface for receiving a callback result from someone. Use this by creating a subclass and implement onReceiveResult.
public class CustomReceiver extends ResultReceiver { public static final String RESULT_RECEIEVER_EXTRA = "receiver";
private Receiver mReceiver;
public CustomeReceiver(Handler handler) {
super(handler);
} @Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
} }// using this interface for transfer data to activity/fragment
public interface Receiver {
public void onReceiveResult(int resultCode, Bundle resultData); } public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}}
then inside a service class you can use put this code. I am using IntentService so my code will look like this:
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// if using customeReceiver
if(intent !=null) {
// Here will get here ResultReceiver object not our Custom Receiver class instance
ResultReceiver receiver = intent.getParcelableExtra(CustomeReceiver.RESULT_RECEIEVER_EXTRA);
// now create a Bundle and put data on that
Bundle bundle = new Bundle();
bundle.putString("data", "data");
receiver.send(1,bundle);
}
and finally our MainActivity will look like
public class MainActivity extends AppCompatActivity implements CustomeReceiver.Receiver{ public CustomeReceiver customeReceiver; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);// using ResultReceiver class
customeReceiver = new CustomeReceiver(new Handler());
customeReceiver.setReceiver(this); Intent serviceIntent = new Intent(this, TestIntentService.class);
serviceIntent.putExtra(CustomeReceiver.RESULT_RECEIEVER_EXTRA, customeReceiver);
startService(serviceIntent);
} @Override
public void onReceiveResult(int resultCode, Bundle resultData) {
Log.d("onReceive", "gotcha "+resultData.getString("data"));
}
Using ServiceConnection class
Using serviceConnection class we can get bound service class object. Our bound service and application are running in same process. So first we have to create an IBinder object that we will use for sending data from activity to bound service class. For creating an IBinder object we need to create a class that will extend Binder class.
public class TestBoundService extends Service {
private final IBinder mBinder = new MyBinder(); @Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
} public class MyBinder extends Binder {
public TestBoundService getBindedService()
{
return TestBoundService.this;
}
} @Override
public void onCreate() {
.....
} @Override
public void onDestroy() {
.....
}}
Now inside MainActivity we will use ServiceConnection class, Interface for monitoring the state of an application service. This class have three methods and they will call on main thread.
onServiceConnected(ComponentName name, IBinder service) : Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
onServiceDisconnected(ComponentName name) Called when a connection to the Service has been lost.
So now inside MainActivity we will call this :
private TestBoundService mBoundService;
private boolean boundStatus; private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// connection with the service has been established
mBoundService = ((TestBoundService.MyBinder)service).getBindedService();// now we have mBoundService( our service object ) we can use it if we want to pass any data } public void onServiceDisconnected(ComponentName className) {
// connection with the service has been unexpectedly disconnected // make it available for GC
mBoundService = null; }
};
source for this activity HERE
Thanks for reading this article. Be sure to click ❤ below to recommend this article if you found it helpful. It means a lot to me. Please mention any other possible ways if you think.
Also, Let’s become friends on Linkedin, GitHub and Facebook.
