image
Services in Android
Start course
Difficulty
Intermediate
Duration
2h 15m
Students
23
Ratings
5/5
Description

This course focuses on lifecycles and intent in Android and then moves on to look at services, receivers, and Android app binding.

Intended Audience

This course is intended for anyone who wants to learn how to start building their own apps on Android.

Prerequisites

To get the most out of this course, you should have some basic knowledge of the fundamentals of Android.

Resources

Course GitHub repo: https://github.com/OakAcademy/android-app-development-with-kotlin/tree/main/Section%207%20-%20Intent%20and%20Lifecycle/Intent 

 

Transcript

Well, hello everyone. We are here; we are back; we are now; and we are talking about Android services in this video. So, first I want to tell you that services are one of the basic features in Android. We develop an Android application, services play up important role. So, because of that, you got to learn services as well, and you got to learn them back to front. So, we're going to talk about services in detail, and by the end you're going to know it all. All right. So, a service is an Android application component and it can perform long-running operations in the background.

Services: It's also an Android component like the other Android components, but it just works in the background. Another feature of services is that there is no user interface. So, services don't need a user interface because it's not going to interact with users. So, normally, other Android components are in interfacing with users, such as mail or password input. You got to click some buttons, things like that. Obviously, services do not need to do that. The service can be started by another Android component though.

For example, when you click a button in an Android application, a service can be started in the background by that particular button. So, if I wanted to give you an example from the real world, well, I can give a file download example. In the application, when you click a download button, a service starts to download the file in the background. Sometimes, this file can be of a really large size; it can take a little while. And a service will take this download task, and just chuck it into the background. Meanwhile you can continue working on the application.

So, in this download example, first, download works in the background. Second, this download service does not have a user interface. It can show the user download bar or notification though, but these aren't really in the activity or in the application. Third though, this service started with a download button, that means, service components started with another button component. So, let me just give you another service example. What about music player applications? That's a great example of services. So, a music player can continue to play selected music in the background. So, another example could be something like this. An application can download a photo from the Internet in the background or application can send information to the server in the background. Of course, you could probably just make lists and lists of examples of services now that you know them. Of course, there are many extensive uses of services in all of these Android applications that you are about to develop.

But let's break it down some more. There are three different types of services in Android applications. So, the first one is foreground services. So, in the foreground services, the user can see the process. For example, your application will download a file in the background; it's a foreground service. In the foreground service, a user needs to see notifications, the download process, or when the download finishes, that information needs to be given to the user. Also, even though the user does not interact with the application, the service has to continue to work in the background. For example, your application starts to download a file in the background. The file could be huge.  Let's say, a gigabyte. Well, while that download process is continuing, the user can continue to work with the application. In fact, let's say, the user leaves the application, the download process has got to continue. I mean, we don't want to get a reputation for flaky services. Anyway, the second one is background services. So, with background services, the user doesn't even see the process.

The application doesn't show any notifications. Sometimes the user just might not even know anything about the service process. It does everything in the background. For example, you develop an application. The application stores some photos in the devices' memory. While the application stores photos in the device, it can compress photos in the background. User doesn't need to know that it's being, it's sitting there compressing photos, or anything like that. Whatever an application does in the background or how an application compresses photos, it doesn't really matter to the user. They don't need to know.

Anyway, the user takes the photos. They wanted the same money wise. While you store these photos in the background, you can create a compression service, and that will run in the background. That way, user takes photos, photos take up less space and memory, and that's going to make your application work better on the phone and have a satisfied user. So, obviously yes, you can compress photos in the background, then whenever the user needs a photos, you can uncompress them again. That's just an example. So, in this service, you're doing some operations in the background and without the user's knowledge; that's the point. Also, the user does not need to interact with that service. The third one though is bound services. So, bound services. This is dependent on the component that calls itself. So, the service interacts with the component permanently that calls itself. When a component that calls itself stops, the service also stops. So, service does not continue to work in the background.

In the literature, this relationship is called client-server relation. So, in this relationship, the server is a service and the client is a component that starts the service. You follow? Music player applications can be an example of bound services. When you start a music player application, the service sends data to the player periodically. So, this data could be whatever, what music is playing? Or, what's the name of the next thing in a playlist? Or, how many minutes of music is playing? How many is left? That kind of thing. So, when the user closes the application, the music should stop. Yes. When you start the application again, music also can start to play again. So, you can see that that's the kind of service that would be in continuous interaction with a component.

And we call that kind of service bound service. Okay so, when you come to the service writing part, there are two service classes. First one is the standard service class. What is the standard service class you might ask. Well, this class is a traditional service class. So, the service class takes on the whole task all by itself. But this service class has a feature that uses the main thread of the application. So, I think that I should give you a few more details for that. So, Android operating system, it will give each application a share of the processor. So, that means that your application uses this amount of the processor. Also, your service will use the same share of that processor. If the service uses most of its share, well, your application is going to slow down.

Because of this if your service has a really big task, you should not use the standard service class. Because that means, it's going to slow your application down, and who wants to have a slow application on their device. But if your service task is small, you can always use the standard service class. So, I'll show you an example. Your application will, let's say, it downloads a movie from the Internet. At the same time, you want to use your application. So, the download process will take some time, and will also use resources of the application. And when you use the application at the same time, it's going to slow down. Users don't want a slow application, so you're going to have to figure out how to solve this problem.

So, in this part, I would say that another service class helps us out, and that is the job intent service class. The job intent service class is a subclass of the service class. The job intent service class does not use the application main thread. It actually creates another work thread and uses its own thread. So, that means, the job intent class requests another share of the processor from Android's operating system. And it does not have a tendency to slow down the application. The job intent service class is used in long-term background process. Okay, so after I've explained that let's just go to Android Studio because I don't want to just give you theory. Theory-shmeory, all I want to do is show you in practice because practice is well, practice is practice. So, let's go to Android Studio. I create a new project and I'll just call this project Services. Now before we start, I do want to show you the finished version. So, you know where we're going. So in this example, we're going to have three buttons.

So, if we click the 'START CLASSIC SERVICE' button, it's going to start a Classic Service. And if we click the  'STOP SERVICE' button, it will stop the service and we will track these steps from the log records. And when the service starts, log records is going to show us that the service has started. And when the service stops, the log records will show us that the service has stopped. Also, when we click on the 'START JOB INTENT SERVICE', this button here, the Job Intent Service starts and after the necessary actions are fulfilled, the service automatically ends. We don't need to take any other separate action just to stop the service. Now also, let's see if you notice we can see the threads used by the Classic Service and the Job Intent Service.

So, our Classic Service class uses the main thread. The Job Intent Service class runs asynchronously in the background that is, it uses a separate thread. So, now we can start designing the project, So, I'm going to add three buttons here. You're doing along with me, right? The first button is to start the Classic Service. Second one is to start the Job Intent Service. Third Button is to stop the Classic Service. So, now I just want to centre these three buttons in the horizontal plane. Now I center the buttons in the vertical plane. So, after that you need to change the text of the buttons. Text of the first button  is Start Classic Service. Text of the second button will be Start Job Intent Service. Text of the third button will be Stop Service. Now I'll give an idea to these buttons, Are you the first button? Well, that can be Start Classic Service. What would the idea of the second button be? Start Job Intent Service. And the idea of the third button can be Stop Classic Service. All right, so after that, I want to define these buttons in the MainActivity.kt file. So, just write in here, lateinit var_startClassicService : Button.

Second line lateinit var_startJobIntentService : Button. And then lastly, lateinit var_stopClassicService : Button. So, in the onCreate() method, startClassicService = findViewById(R.id.startClassicService). Next, startJobIntentService = findViewById(R.id.startJobIntentService). And then last up, stopClassicService =  findViewById(R.id.stopClassicService). All right, so what do you think is next? I'll just add in some click listeners to the buttons. Now, you know how I'm going to add click listeners, right? Well, everything that we've done until now is just a standard part. So, in other words after that we need a Service Class to run the service. So firstly, I just want to write the necessary code for Classic Service Class. And after the Classic Service Class, we will learn the Job Intent Service Class. So, now I want to create a Classic Service Class. I will right click to the 'MainActivity.kt Class', select 'New' 'Kotlin Class/File'. I'll need to give a name to this class and the name will be ClassicServicesExample. After pressing the enter key, Android Studio creates the ClassicServiceExample class. The ClassicServiceExample Class needs to extend the Service Class.

So, after the colon I will write Service. Of course, we mentioned two Service Classes: Standard Service Class, Job Intent Service Class. So, first we will extend, the Standard Service Class. I will select the Abstract Service Class that comes from the Android dot app. And when I extend the Service Class, Android Studio wants to add methods and I can just select from here, Implement members'. It will add this method. So, you see Android Studio added the bind method(). Do you remember we mentioned the bound service before will not create a bound service though because we're not going to use that method but, it's got to stay here.

So for this, I'm just going to delete this line and instead of this line, I will write return null. That's how that works. And I'm going to add some other functions myself. So, the first function will be the onCreate() function. So, the second function will be the onStart command() function. And the last function will be the onDestroy() function. And we will write service code in these methods. We'll write in the onCreate() method.

The operations that should be done when the service is first created. So, we're going to write in the onStart command() method, the operations that should be done when the service is started. So, we'll write in the onDestroy() method the operations should be done when the service is stopped. And what do you want the service to do? Well, you're going to write them into these sections. For example, if you want to download a picture from the internet, you'll write these codes in this class. We will not write a service in this video. I just wanted to check, make sure that you see how the system is working or not, out of trouble shoot. So, in fact, let's do that right now. If I want to check when I create a service, I'll need to see whether this onCreate() method is working or not. So, to see these methods work, I'll need to add log records into these methods. So, first I will add in the onCreate() method. You remember from the previous videos, how we add the log records? Log records take two parameters. First one is title. I'll just write service for the title. Second one, is the message and I'll write Classic Service is created something like that. You can write.

So, I'll write the same code in the onStart() command method. I'll just change the message and I'll write Classic Service is started. Also I want to show you that the Classic Service Class uses the main thread. So, what I'll do is create another log record here. The tag for this can be Thread. And as a message, I'll write Thread.currentThread().name. And then lastly, in the onDestroy() method, I'll write "Classic Service is stopped." So, how will I run this service? So, we have a Service Class. We also have the Main Activity Class. Now, can you remember way back when we talked about services we said that a component should start the service. So, in this example our component is the button. So, we need to do one more thing at this part. Remember or can you think or can you project or I'll just do it. We need to define the Service Class in the manifests file. So, that means I'm going to open the manifest file. Here under activity xml code, I will open a new tag just by pressing the '<' key on the keyboard. Now write service and press 'Enter'.

So, in this part I just need to write this service class name and it is the ClassicServiceExample. So, after that we'll need to write code to run the service. So, I'll open up the MainActivity.kt class. I'll write the necessary code inside the ClickListener of the startClassicService button, and I can start this service just by using the Intent method. So, I'll write here, val intent = Intent(). Intent class will take two parameters. The first one is this@MainActivity. The second one is the ClassicServiceExample : : class.java. In the second line, I'm going to write startService(intent). So, this startService command will start the service. After that, I'll open up the 'Logcat' screen, and in the log records, I'm going to select 'Debug' records, and in the search area, I will write Service. So, now we can run the application. Well check it out, my friends, application is working. Now, when I click the 'start service button', in the log records we can see, "Classic Service is created"; that's the message. "Classic Service is started"; that's the expression. So, first the service is created then after that, the service is started. Follow?

And we can also see that the Classic Service uses the main thread. All right, so now the service is running, and you see it right before your very eyes. After service started, if I click the 'Start Service' button again, you can see here that this time I'll just write service is started, because when you first created service, after that's not going to create it again until you stop the service, so it's just going to start again created service. That's all. Also, I need to tell you this, if I write here stopSelf() as a method, it will stop the service automatically after the service finishes the task. For example, if your service task is, let's say, to download a file from the Internet, the server will stop automatically, after it finishes the download. All right, so let's run it again and see how this method works. And you can see here when I click the 'Start Service' button in the log records, service is created, service is started, and service is stopped. Now, I have not stopped the service yet, but it stopped automatically.

So, that's how the stopSelf() method works. If I do want to stop the service manually, I'll just write my code in the stopClassicService button. I'll just write here, the same Intent method. In the second line, I will write stopService(intent). So, now when I click on the 'stopService' button, the stopService method will work. In the service class, the onDestroy() method will work.  In the onDestroy() method, this Log record will work, and I will convert this stopSelf() method to the command line. All right, so let's run the application again. Okay, so the application opens, first I'll start the service. Now, when I click the 'Start Service' button, it writes, "Service is created" and "Service is started". So, when I click the 'Stop Service' button, it writes "Service is stopped". All right, so there's an example of the ClassicService class. Now, also you've got to remember there is this other service class: JobIntentService, ClassicService class of course, uses the main thread, but the JobIntentService class creates its own thread. So, let's do that.

Okay, for the JobIntentService, I want to create a new Kotlin class, the name of this class can be JobIntentServiceExample. All right, so this time I'm going to extend the JobIntentService class. So, after the " : " sign, I will write JobIntentService. And notice that the JobIntentService class is deprecated. Normally, the IntentService class would be used to separate the thread from the main thread, but later on the IntentService class was deprecated and the JobIntentService class was used instead. But then later the Android community created a structure called WorkManager for background processes and then reported that using WorkManager for background processes would be more compatible with Android Jetpack, and that's how we get the JobIntentService class deprecation. But all that being said, I still want to show you how to use this class. We're going to learn about the WorkManager in coming lessons, but it's just really useful to know how the JobIntentService class works. All right, let's continue.

So, when I click here, and select 'Implement members', I will add the onHandleWork method. I'm just going to delete this part. It's not necessary. But instead, I'm just going to write Log records. Tag will be "Service", message will be "Job IntentService is started". Also, I will create another Log record here for thread. Now, this will be the same as in the ClassicService class. So, I'm going to copy the log record from the ClassicService class and paste it here. Also, we should create a new function. So, the name of this function can be myBackgroundService(). Also, this function is going to take two parameters. The first one is the context, and the second one is the intent and inside this function, now we've got to call the enqueueWork(). Yes, it's French. But anyway, it's a function that is predefined by the platform, and this function will take four parameters. The first one is the context object. Second one is the name of the service class, which is JobIntentServiceExample : : class.java. Third parameter is the jobId. So, you should write a unique integer value for this service. I'll just write one. And the last parameter will be the intent object.

Now I will also enclose this class in the companion object scope to directly access the myBackgroundService function from the main activity; otherwise to use and to access functions or variables in a class we'll need to create an object from that class. But if we just write it like this, we can access this function directly using the class name. That's cool. Okay. So, finally I'll call the onDestroy method to observe that the service is stopped. I also want to create a Log record. The tag can be "Service", message can be "Job Intent Service is stopped". So, now the JobIntentService class is ready, but if we're going to use the JobIntent class, we should make some definitions in the Manifest File. So, that means I'll open up the Manifest File.

Now first under the activity tag, I'll need to create a new service tag and this time I'm going to select the 'JobIntentServiceExample'. Also, I'll need you to find a permission here. So, I'll write, Android, I will write android:permission. Inside ", I'll write "android. permission. with a capital letter BIND_JOB_SERVICE". No, I'm not yelling. So, finally, above the application tag, there is one more permission we need to get, and that permission is called the WAKE_LOCK permission. So, I'm going to open a new tag and I'll write uses-permission here; press 'Enter'. Here, I select 'WAKE_LOCK' permission. All right, so now we can start the service in the MainActivity. Open up the 'MainActivity.kt' class. I write the necessary code inside the ClickListener of the startJobIntentService button, and I will start this service using the intent method.

So, what will I write here?  val intent = Intent and the intent class takes two parameters. First one is, this@MainActivity, and the second one is, the JobIntentServiceExample : : class.java. Second line, I will call the myBackgroundService function that we created in the JobIntentServiceExample class. So, I'll write, JobIntentServiceExample.myBackgroundService(). If we didn't create the myBackgroundService function inside the companion object scope, well, we couldn't access this function directly. In this case first, we had to create an object from the service class in the MainActivity, and then we could access the myBackgroundService using this object. So, that's how that works. Let's continue.

So, the function is going to take two parameters. First one is context; we can write this@MainActivity, and the second one is intent, object we create here. Okay, so now everything looks ready, let's go ahead and run the application. And the app opens. I'm always amazed. So, when I click the 'Start Job Intent Service' button in the log records, you see how you can see the Job IntentService is started and the Job Intent Service is stopped. We can also see that the JobIntent class does not use the main thread. And I didn't even have to write the stopSelf() method. It stopped the service itself. The JobIntentService handles everything itself. And it's all grown up, so when it finishes the task, it just stops the service itself, that's all. That's all you need to know. Move along. So, that's services in Android applications. I really hope it's useful for you, because you're going to be using it soon. All right. I'll see you in the next video.

About the Author

Mehmet graduated from the Electrical & Electronics Engineering Department of the Turkish Military Academy in 2014 and then worked in the Turkish Armed Forces for four years. Later, he decided to become an instructor to share what he knew about programming with his students. He’s currently an Android instructor, is married, and has a daughter.

Covered Topics