Understanding Service, IntentService and BindService of android

Sharing is caring!

Service is the most important component in android. Service is running in background It means that it does not have the user interface. It is an independent of activity means it does not matter if an activity is running or destroyed, service always running in the background. Service is used for long background task it could be anything.

There are two types of service.
1. Started service or unbound service
2. Bound service.

Started service

Started service are those service that started by Activity or broadcast receiver client and it is independent of activity. It will always be running in the background. Service only killed by Android resource when anything happens wrong for example memory is not available or not enough memory to execute the task.

There are two types of started service.

1. Which extends to Service Class
2. Which extends to IntentService Class.

Let’s see what are the basic difference between these two services and where we can be used this services?

Service 

Service which is running on the main thread it should not be any long operation kind of task. But it does not matter, Here you can create your worker thread also for any long-running task.
Service will continue running in the background it does not matter it is completed the task or not, that why it is the cause of draining the battery. It will only stop when you need to call the stopSelf() method on particular task Id.  For every task, it contains one task Id. You need to stop the service once it task has completed. So, in this case, you can avoid battery draining.

If you have started multiple tasks inside the service then it will parallel running all task. We have not sure which task will finish first and which one in last. Whenever you start your service either from Activity or Broadcast Receiver it’s life cycle will start executing.

onCreate() -> onStartCommand() -> onDestroy()

Let’s see an example to better understanding.

public class TestService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }

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

        doSomeTask(startId); // Here you do some task
        return super.onStartCommand(intent, flags, startId);

    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private void doSomeTask(int startId) {
        
        stopSelf(startId); // stop service if your task completed
    }
}

onCreate() called means service is created, And after onStartCommand() called it means service running in the background. Here you can execute your task. onDestroy() called means your service has finished or killed.

As I above discussed that your service will destroy or killed by Android OS if anything happened wrong like low memory or memory is not enough to execute the task. But we don’t want sometimes our service is stopped, we want it will again restart when memory comes available. In this case, we can make our service as per our requirement. Service provides the option for you to make accordingly. You can set the flag.

1. START_STICKY – When you set your service is started sticky it means it will restart your service again by Android when memory is available to execute the task. But before make sure that you do not pass any intent data because intent data will be lost when service is killed. So we will receive null intent data on startCommand().

2. START_NOT_STICKY – When you set the flag to start not sticky then it will not start your service if it killed by android resource and some more flag are available you can check on the official developer site. You can set your flag as below.

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

        doSomeTask(startId); // Here you do some task
        return START_STICKY;   // you can set the flag as per your requirement.

    }

This is all about the service. Let’s check for intent service.

IntentService

Intent service is running on the worker thread, not by main thread or UI thread. You can not update any UI here because it always running by the background thread. It can be used for long operation kind of task for example for downloading files from the server etc.

It can also start service from activity or broadcast receiver. When you start service from here itslife cycle method will be executed.
onCreate() -> onHandleIntent() -> onDestroy().

public class TestIntentService extends IntentService {

    public TestIntentService(String s){
        super(s);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
         doSomeTask(); // do your task
    }

    private void doSomeTask() {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

Service is created once called the onCreate() and after it will be running on onHandleIntent(). Here you can do some task. Service will destroy it will be called onDestroy() method. Intent service automatically stopped once it will complete the task.

If you have multiple tasks running it will handle one task at one time and other tasks will be in a queue.
Once the current task is completed then it will take next task from the queue.

Bound service

Bound service is one that allows binding service with the client. This service will continue running the client unbind it. This service will start running when it binds to bindService(). This kind of service provides the option to the client with either in the same process or different process. For the different process, it binds remotely by IPC (inter-process communication).
Inter-process communication provides to run service in a separate thread or multiple threads. For single thread process it will execute by Messenger and for multiple threads, it will handle by AIDL (Android Interface Definition Language)  for example audio, video playing etc.

Let’s first check How it works bind service in the application. Service can bind either by activity or broadcast. What you need to do just call bindService(). For binding the service You need to pass the IBinder instance in onBind() life cycle of service. Whenever your task has completed then unBind() service from the client. Here is an example to understand the concept.

public class MyService extends Service{

    private final IBinder mBinder = new LocalService();

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

    public class LocalService extends Binder{

        MyService getService(){
            return MyService.this;
        }
    }

    public String getFirstMessage(){
        return "Hi, I am sunil";
    }

    public String getSecondMessage(){
        return "Good to see you.";
    }
}

Let’s create an activity to bind this service and access this method inside the client.

public class BindServiceActivity extends AppCompatActivity {

    MyService myService;
    private boolean isBind;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_service);

        ((Button) findViewById(R.id.btn_start)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getServiceMessage();
            }
        });
    }


    private void getServiceMessage() {
        // call the localService methods Here
        String firstMessage = myService.getFirstMessage();
        String secondMessage = myService.getSecondMessage();
        Toast.makeText(BindServiceActivity.this, firstMessage + " " + secondMessage, Toast.LENGTH_LONG).show();
    }

    // Here need to create the service connection
    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // get the locala service instance
            MyService.LocalService localService = (MyService.LocalService) service;
            myService = localService.getService();
            isBind = true;


        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
        }
    };


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

    @Override
    protected void onStop() {
        super.onStop();
        if (isBind) {
            unbindService(serviceConnection);
        }
    }
}

Here is required ServiceConnection instance to create the connection between client and server. You can bind the service in onStart() method and unbndService() in onStop() method. But it’s per your requirement When we can unbind service.

In my next tutorial, I will focus on IPC Remote connection for bind service for a single thread (Messenger) and multiple threads(AIDL). To understand the reactive Rx I would be recommended to check these posts of understanding of Java 8 stream and Rx Observables, and basic understanding and practice features and functions of RxJava, and understanding practice RxJava with RxBinding in Android.

Thanks for reading this post. I used the reference from my old post which is posted here. Please do subscribe your email to get every newsletter from this blog and if you feel that this post helps you then do not forget to share and comment below.

Happy Coding 🙂

5 2 votes
Article Rating

Similar Posts

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments