Cosc 54730 Android Services Job Services and Work
Cosc 5/4730 Android Services, Job. Services, and Work. Manager
SERVICES
Reminder • Android applications normally have one or more of the following: – Activity/fragment • Provides a screen which a user interacts with. – Service • an application component that can perform long-running operations in the background without a user interface – Broadcast. Receiver • This is way to receive information from other applications and the OS. – Content. Provider • You app is providing information to another app and itself via a encapsulated data structure
What is a service? • From android developer web pages: • Most confusion about the Service class actually revolves around what it is not: – A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of. – A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors). • Thus a Service itself is actually very simple, providing two main features: – A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not directly interacting with the application). This corresponds to calls to Context. start. Service(), which ask the system to schedule work for the service, to be run until the service or someone else explicitly stop it. – A facility for an application to expose some of its functionality to other applications. This corresponds to calls to Context. bind. Service(), which allows a long-standing connection to be made to the service in order to interact with it. http: //developer. android. com/reference/android/app/Service. html
What is a service? (2) • Basically a service can be though of as a data structure that runs. • It doesn’t need a screen – Normally communicates with an activity in the application. • It can run in parallel with an activity providing data and stuff. (binding) • it may run without activity, to provide data for later use. – Say an alarm starts it every X minutes to check on something. • Then may use a handler, notification, call a broadcast receiver, or even start an activity. • Or my just write out the data to local storage, for later use.
What is a service? (3) • Example – Use clicks on a picture that they want to download from the web into their gallery. – The application kicks off a downloader service and then the user continues. – The service downloads the picture and puts into the gallery. • And creates a Notification when done that the picture has completed (or failed). The user can click on the notification and open the picture (using the gallery app).
What is a service (4) • Starting a service – You app can start a service with start. Service call. The service will then run in the background – You are responsible for stopping it • Either stopself() (in the service) or stop. Service in the app. • Binding to a service – You app is bound to the service (and it’s started), normally with a RPC, with bind. Service • The service returns a IBinder method, which allows the app communicate directly with the service. • If you service won’t allow binding, then the IBinder returns null.
What is a service? (5) • Service – This is the base class for all services. When you extend this class, it's important that you create a new thread in which to do all the service's work, because the service uses your application's main thread, by default, which could slow the performance of any activity your application is running. • Intent. Service – This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don't require that your service handle multiple requests simultaneously. All you need to do is implement on. Handle. Intent(), which receives the intent for each start request so you can do the background work. – You can override other methods as needed like you would need in a Service.
Intent. Service • Easy to implement • Create a constructor with a super("name") • Override on. Handle. Intent(Intent) { …} – Inside is the work to be done. – The Extra bundle tells you what "to process". – Send broadcast intent or notification when "completed". • May also send a message back to the activity via handler, by putting the messenger object in the Bundle!
Intent. Service Example public class my. Intent. Service extends Intent. Service { • required constructor public my. Intent. Service() { super(“my. Intent. Service"); } • Where we do the work. @Override protected void on. Handle. Intent(Intent intent) { Bundle extras = intent. get. Extras(); //now get the information you need to do whatever is needed. } } See the my. Intent. Service. java for the compete code. In the service repo, service. Demo example
Calling the Intent. Service • From the application we create an intent and then start the service. – The example service “returns” X number of random numbers based on the intent, so Intent number 5 = new Intent(get. Base. Context(), my. Intent. Service. class); number 5. put. Extra("times", 5); //5 random number – And we want it to send numbers back through a messenger (handler) Messenger messenger = new Messenger(handler); number 5. put. Extra("MESSENGER", messenger); • As note, If there is no MESSENGER key, then the service will use notifications. – And finally start the service, using the intent that was created start. Service(number 5);
Service. • Far more complex. – Need to create thread for it – The service. Handler as well – Onstartcommand which will get the intent and then pass the information onto the servicehandler (via a messenger) so it off on it’s own thread. – You can also setup the IBinder as well. – Well look at the template for the service code next.
Service code public class my. Service extends Service { private Looper m. Service. Looper; private Service. Handler m. Service. Handler; //our global variables here. // Handler that receives messages from the thread private final class Service. Handler extends Handler { public Service. Handler(Looper looper) { super(looper); } @Override public void handle. Message(Message msg) { //our code here, to the work based on the msg. } // Stop the service using the start. Id, so that we don't stop // the service in the middle of handling another job stop. Self(msg. arg 1); } } @Override public void on. Create() { // Start up the thread running the service. Note that // we create a separate thread because the service // normally runs in the process's main thread, which we // don't want to block. We also make it // background priority so CPU-intensive work will not // disrupt our UI. Handler. Thread thread = new Handler. Thread("Service. Start. Arguments", Process. THREAD_PRIORITY_BACKGROUND); thread. start(); // Get the Handler. Thread's Looper and use it for our Handler m. Service. Looper = thread. get. Looper(); m. Service. Handler = new Service. Handler(m. Service. Looper); }
Service code (2) @Override public int on. Start. Command(Intent intent, int flags, int start. Id) { Toast. make. Text(this, "service starting", Toast. LENGTH_SHORT). show(); // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job Message msg = m. Service. Handler. obtain. Message(); msg. arg 1 = start. Id; m. Service. Handler. send. Message(msg); // If we get killed, don’t restart, wait for a startservice() to startup again. return START_NOT_STICKY; } @Override public IBinder on. Bind(Intent intent) { // We don't provide binding, so return null; } @Override public void on. Destroy() { Toast. make. Text(this, "service done", Toast. LENGTH_SHORT). show(); } }
Service code (3) • In the App Intent intent = new Intent(this, my. Service. class); start. Service(intent); – The start. Service() method returns immediately and the Android system calls the service's on. Start. Command() method. – If the service is not already running, the system first calls on. Create(), then calls on. Start. Command().
Service code example. • I’m using the template code from before and adding to it where listed in red text. – I copied the code from the developer site – http: //developer. android. com/guide/components/services. html#Ext ending. Service – You may need to initialize some things in the On. Create() and/or On. Start. Command(…) as well.
Service. Demo • Remember a service, is just like an activity, except there is no screen. – So most of the Demo code is downloading files and using file I/O and the notification system. • Nothing really amazing at this point. – When you need a service, you start it with an intent and the start. Service(intent) command. • Just like you would an activity. • The service ends when they are done and what for the next call.
API 26+ and services. • Background Execution limits – Background services are now limited. • Any background service with an activity running is allowed – Once the activity is done or pushed into the background, the service is killed. • Any "foreground" service is allowed. – This is started in the foreground and have a persistent notification attached to it. • High-priority Firebase Cloud Messages (not normal priority) • Executing of a penting. Itent from a notification is allowed – for a short period, roughly 5 seconds. • Use Job. Schedulers or the new Work. Manager.
Foreground services • From the activity/receiver (API 26+ method) – start. Foreground. Service(Intent i); • You have a few seconds in the service to do the following: – So do it first. • Build a persistent notification (don't send it). • start. Foreground(int ID, notification); – A note, in Androidx, start. Foreground. Service also requires a (non dangerous) <uses-permission android: name="android. permission. FOREGROUND_SERVICE"/> in the manifest file.
AIDL • Android Interface Definition Language (AIDL) – similar to other IDLs if you have worked with them before. • It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication (IPC). – We are not covering AIDL, in this class • http: //developer. android. com/guide/components/aidl. html
Bound Services • A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC). – You need to implement the on. Bind() method and return a IBinder an IBinder object. – The activity uses the object to “call into” the service. • Or get a handler and send messages to the service. • You can also use the AIDL as well.
Binder • In it’s simplest form, you allow the activity to call methods in the running service via the binder service. – Instead of start. Service • Bind. Service(intent, Service. Connection, flags) • Now you use the Service. Connection variable to call into the service to retrieve data or cause the service to do something.
Binder implementation • In your service, create an instance of Binder that either: – contains public methods that the client can call – returns the current Service instance, which has public methods the client can call – or, returns an instance of another class hosted by the service with public methods the client can call • Return this instance of Binder from the on. Bind() callback method. • In the Activity/fragment/whatever, receive the Binder from the on. Service. Connected() callback method and make calls to the bound service using the methods provided. – Lets look at the example code for see how the pieces go together • Service. Demo. IPC uses binder so the activity can use it’s methods • Service. Demo. MSG uses the binder to setup a handler to send messages to the service.
Manifest file. • Like everything else services must be registered listed in the Android. Manifest. xml – Uses the <service> tag and is pretty simple. – Example: <service android: name=". my. Intent. Service“ android: enabled="true" android: exported="true"> </service>
Example code. • The Service. Demo – One example intent service for random numbers – One Example Service for random numbers • You can compare the complexity of a service with an intent. Service – file. Dl. Service is an intent. Service. • It takes a URL (http: //. . . ) to down a picture and stores in the SD card downloads directory. • When completed it sends a notification, so the user can open the file in the gallery viewer.
Example code (2) • Service. Demo. IPC – Uses a Service. Connection to allow the activity to call into the service to get a random number – Based on Googles code. • Service. Demo. MSG – Setups a handler to send messages to a service • This service will toast a message. • But you can easily change that to have the service do many difference things, based on the message.
References • http: //developer. android. com/reference/android/app/Service. html • http: //www. vogella. com/articles/Android. Services/article. html • http: //developer. android. com/guide/components/services. ht ml – http: //developer. android. com/guide/components/aidl. html – http: //developer. android. com/guide/components/boundservices. html
JOB SERVICES (BRIEFLY)
Job Services • There is a Job. Intent. Service and a Job. Service – Job. Intent. Service is like a Intent. Service and it is located androidx. core • androidx. core. app. Job. Intent. Service – Job. Service starts in API 21, more added in 23, plus new work. Items in 26, but is not in androidx – Android 11 offers debugging support for apps to identify potential Job. Scheduler API invocations that have exceeded certain rate limits. • Developers can use this facility to identify potential performance issues. For apps with the debuggable manifest attribute set to true, Job. Scheduler API invocations beyond the rate limits will return RESULT_FAILURE. Limits are set such that legitimate use cases should not be affected.
Job. Intent. Service public class My. Job. Intent. Service extends Job. Intent. Service { @Override protected void on. Handle. Work(Intent intent) { • We have received work to do. The system or framework is already holding a wake lock for us at this point, so we can just go. } • Convenience method for enqueuing work in to this service. • Call this method, with an intent and it will start up the job. static void enqueue. Work(Context context, Intent work) { enqueue. Work(context, My. Job. Intent. Service. class, JOB_ID, work); } }
Job. Service • Job. Service requires a Job. Info to be built. – Give a time frame to run in and if any events are involved. • Such as run this job when the device when it on the charger. • Like the standard Service there a number of parts to jobservice class
Example code • There is a Job. Intent. Service and Job. Service example code – These produce simple random numbers – Gives you a framework of both the services.
Architecture WORKMANAGER
Schedule tasks with Work. Manager • The Work. Manager API makes it easy to specify deferrable, asynchronous tasks and when they should run. • These APIs let you create a task and hand it off to Work. Manager to run immediately or at an appropriate time. – For example, an app might need to download new resources from the network from time to time. – Using these classes, you can set up a task, choose appropriate circumstances for it to run (like "only while device is charging and online"), and hand it off to Work. Manager to run when the conditions are met. • The task is still guaranteed to run, even if your app is force-quit or the device is rebooted. – You can check a task's state and its return vales by observing its Live. Data and update the UI for status. https: //developer. android. com/topic/libraries/architecture/workmanager
adding to your project implementation 'androidx. work: work-runtime: 2. 2. 0' • There used to be firebase job scheduler part, but it been fulling subsumed into the Worker and Listenable. Worker
Components and concepts. • Worker: the app extends the Abstract Worker class to perform the work here. • Work. Request: specifies which worker class should perform the task. – Specific information such as when and what circumstances to run as well. There is a Work. Request. Builder • Work. Manager: enqueues and manages the work requests. – The manager will schedule the task • Work. Status gives info about a task. Work. Manager provides a Live. Data for each Work. Request. The live. Data holds the Work. Status object. You can observe the Live. Data to determine status.
Running tasks. • A task can be "One. Time. Work. Request" or a recurring task. – Recurring tasks use a Periodic. Work. Request that specifices how often the task is run, say once every 24 hours. • We can chain tasks together as well. Say you need to run A, B, then C. – Or run some in parallel as well, so run A 1 and A 2, then B, then C 1 and C 2. – Or even more complex chains of tasks.
Work example • The Work. Manager. Demo has examples – one shot, ie run a task. – sending parameters to a task and getting results. – a chain of workers A and B (in parallel), and worker C waiting until both are complete.
References • • https: //developer. android. com/about/versions/oreo/background. html https: //www. intertech. com/Blog/android-development-tutorial-job-scheduler/ https: //developer. android. com/reference/android/app/job/Job. Scheduler. html https: //developer. android. com/reference/android/app/job/Job. Work. Item. html – API 26+ allows you enqueue and then dequeuer intents as job items – https: //developer. android. com/reference/android/app/job/Job. Parameters. html#deque ue. Work() • http: //www. vogella. com/tutorials/Android. Task. Scheduling/article. html • https: //github. com/googlesamples/android-Job. Scheduler • https: //developer. android. com/topic/libraries/architecture/workmanager
Q&A
- Slides: 40