Ques about working of IntentService - android

I am a beginner in Android App Development. I am trying to implement IntentService to run a process in the background when the user taps on the 'Start Service' button in main activity. The process is small, and usually finishes off right after few seconds of tapping the button. But that small process has to be run periodically, even after the app closes. Here is the code:
protected void onHandleIntent(Intent intent)
{
Log.i(TAG, "The service has now started");
//getting the source code of a html link
Log.i(TAG,"Task has been completed");
}
If I keep the Main Activity opened during the IntentService process, I get both the messages in the Log Cat. But if I close the app right after pressing the 'Start Service' button in Main Activity, I get only the first message i.e. 'The service has now started'. Does this mean that the process doesn't finish if I close the app? Why is this happening? What should I do to overcome this problem?

According to IntentService docs, there is no link between your service and the application main thread.
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand. Clients send requests
through startService(Intent) calls; the service is started as needed,
handles each Intent in turn using a worker thread, and stops itself
when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks
from an application's main thread. The IntentService class exists to
simplify this pattern and take care of the mechanics. To use it,
extend IntentService and implement onHandleIntent(Intent).
IntentService will receive the Intents, launch a worker thread, and
stop the service as appropriate.
I think you aren't getting the log in LogCat because application closes. But the service are logging without your application tag.

Related

Android - Service or IntentService?

I have an app that runs certain "long" process when it is opened or when the device is booted.
The process performs certain amount of downloads via the download manager, and when the process finishes it sends a broadcast event to the app, to capture some analytics.
As I understand, whenever the boot broadcast event is called, the Application class is intantiated (if not in memory already).
Application class is also initiated when the user opens the app.
Based on that, the code to run the proccess is placed inside onCreate method of the Application class. (the process starts a new thread from there)
However, it appears that the "long" process is taking more than the time-to-live of the boot broadcast receiver (about 10s?), so the app process is killed. Then a couple of seconds later, after the download is finished a second broadcast is sent and the app is started again calling Application.onCreate again, with some undesirable effects.
The process was expected to run in a single linear way and not calling again onCreate.
As this process happens only once, I was thinking on creating a Service to give more time to the app to stay alive. However the process depends on DownloadManager so:
1) Using IntentService won't work (as I understand) because the process is still killed after handleIntent returns. The process creates new threads so its tasks are async, and handleIntent method will return before the whole process finishes.
2) Should I create a Service which is simply 'alive' for some time and then is stopped after the process finishes?
3) As an additional question, if I have a running Service, will Application class be instantiated and kept in memory until the Service is stopped?
If you do this only once, you should just create your own Service. When your app starts, call startService(). In onStartCommand() of your Service, start a background Thread that does what you want and return START_STICKY (This keeps your Service running until you stop it). When the Thread completes, call stopSelf() on the Service.
Of course, you can use IntentService, but that class is just an extension of Service that provides another layer of convenience for you. IntentService manages a pool of background threads and takes care of starting and stopping the Service when it runs out of work. This is probably overkill for what you need, but go ahead and use it if you want. The tradeoffs here are negligible.
NOTE: <opinion>For some reason, lots of developers seem to like certain "fad" solutions, like AsyncTask, IntentService, and Event Bus. There are plenty of other ways to solve problems. There is no "one size fits all" in software development.</opinion>
You could still use an Intent Service, you just need to block while the background task is running. Implementation could work like this:
Put it in a service, an IntentService could work like so:
public class DownloadIntentService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
//get url or whatever from intent
//kick off async code to start the download, something like eg:
DownloadTask downloadTask = new DownloadTask(url);
downloadTask.setListener(new Listener() {
public void onComplete(Download download) {
DownloadIntentService.this.notify();
}
}
downloadTask.start()
wait();
}

When starting a service in android, does the ui thread need to go to wait in order for it to start?

I have encountered a problem while writing tests for my activity which made me wonder about this issue. I'm using ActivityInstrumentationTestCase2 and my activity sends intents to the service using startService when a button is clicked and it works fine. (My service is a singelton so i can know if it is running)
When in testing I'm doing the following:
assert service isn't running.
send intent to start the service (or press the button tried both)
wait for the service to start and assert it is running
sounds pretty simple but when i try to wait using Thread.sleep the service wont start, and same for when i try doing busy waiting. So i assumed it will need to finish the testMethod to start the service and i made the following design:
Thread helper;
#Override
tearDown() {
if (helper) join helper
super.tearDown
}
testMethod() {
assert stuff
send intent
start helper
finish
}
helperMethod() {
wait for service to start
assert stuff
}
this actually works, my guess is that it lets the main thread to finish the testMethod and then the intents are handled and my test finishes. This behavior seems very odd as i would expect that the service will start immediately as it is on the same thread or sleeping for enough time will let the service start. So anyone knows what are the conditions for the service to start, and when it happens?
Services are running on the main thread. So if you call Thread.sleep() your service won't start until the time is up.
From the Service document http://developer.android.com/reference/android/app/Service.html
Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work.

Please, explain some Android Service Concepts

I'm just approaching Android Services, but i have many doubts. Here there are some questions.
Before starting, notice i have read those pages
Android Services (official)
Bounded Services (official)
plus sone Inner classes theory in my language. Please be patient, i'm still a bit confused.
1) First of all, a Services differentiates itself from an AsyncTask mainly because it continues to run also if the app is paused (i.e. the user is watching another app); AsyncTask is stopped in that cases. Is it ok or am i wrong?
2) A Service runs in the same thread of the activity that started it through startService().
To not affect the Activity's performances, i have to create a separate thread for that Service, for example implementing the Runnable interface. Another method is making a service that extends IntentService, which automatically provides a new thread for the service: a new thread is created on any onHandleIntent() call.
Now, let's look at my concrete problem. I need to create a Service that will be used by many Activities: his task will be to connect to the server DB every 60 seconds and check for news. If a news is found, notify there's a new news (if we are on MainActivity) or show the new news's title (if we are in the news reader). How should i code it?
I have made a MainActivity that instantiate a NewsService and immediately calls startService(). On the other side, i have the NewsService extends IntentService, that (creates a new thread when onHandleIntent is called?) and looks for new news. Is it a bad idea to use a IntentService? I realized it will be very ugly to start the service calling startService() indefinitely.
At the start of this exercize i tought it was a good solution because it automatically creates a new thread and makes Service implementation simple. But now i have some doubts (i can't know if there's a news! How can MainActivity know it? And how to get the title)
This should be done with a normal extends Thread class, that makes an infinite cicle in it's run() method, checking for news every 60 seconds and, if there's a new one, reads the title from remote DB AND update activities buttons/views. Then if the App will be closed by user, the Service will be closed too.
But the problem is that if i istantiate such class it's work will be stopped when the MainActivity is paused or stopped, and other Activities (the NewsReader in this case) cannot get any update because the new thread isn't getting news at the moment. So i need a Service.
I hope it's clear. How should i implement a solution in the right way?
Please highlight everything wrong in my text, i really need to learn :D
You seem to have understood everything correctly.
As to your specific problem, I'd recommend the following:
Use AlarmManager to schedule your service. Don't let the Service run when it does not have to.
Use a Broadcast Intent for new news. All Activities will have to have an inner BroadcastReceiver that listens for the Broadcast intent of the service and reacts accordingly.
Services are a good approach for what you want, they are pretty good to do processes that consume few resources like keeping a daemon in background, they are also good to show notifications without an activity and keep running even if you exit the activity.
When you need to do more heavy operations in your service you can still use an AsyncTask, launch it, execute your operation in another thread and automatically receive the result in your main thread.
If you want to keep the service always running you can use START_STICKY in your Service
#Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
// Ensure the service will restart if it dies
return START_STICKY;
}
And you can launch the service doing:
final Intent service = new Intent();
service.setComponent(new ComponentName(YourService.PACKAGE_NAME,
YourService.SERVICE_FULL_NAME));
// Start the service
context.startService(service);
1) First of all, a Services differentiates itself from an AsyncTask
mainly because it continues to run also if the app is paused (i.e. the
user is watching another app); AsyncTask is stopped in that cases. Is
it ok or am i wrong?
This is not correct. AsyncTask is a mechanism for offloading background processing into a separate thread and provides a mechanism for informing the user of progress, error and completion of that background processing. AsyncTask does not stop working if the app is paused. It continues to perform its processing in the background. In general, there is tight coupling between an AsyncTask and the Activity that started it.
A Service, on the other hand, is (generally) completely decoupled from the Activity that started it. A Service has its own lifecycle which is independent of the other activities in the app. Also, services have no UI, so they are not linked to the visual elements of the application and they provide no (direct) mechanisms for visual feedback related to progress, error or completion. This needs to programmed separately.
2) A Service runs in the same thread of the
activity that started it through startService(). To not affect the
Activity's performances, i have to create a separate thread for that
Service, for example implementing the Runnable interface. Another
method is making a service that extends IntentService, which
automatically provides a new thread for the service: a new thread is
created on any onHandleIntent() call.
This isn't correct either. A Service doesn't run on any specific thread. The lifecycle methods of a Service (onCreate(), onStartCommand(), etc.) run on the main (UI) thread, which may or may not be the same thread that called startService(). However, a Service can (and usually does) start other background threads, as many as it needs to, to perform the necessary work.
IntentService is a specific kind of Service which manages one or more worker threads that it uses to perform background processing. You send a "command" to an IntentService and the IntentService then puts your command in a queue. At some point (different implementations in different Android versions behave differently), your "command" is dequeued and processed in a background thread. IntentService stops itself after all the "commands" have been processed. IntentService is often not the best choice for a Service due to the way it behaves.
IntentService is definitely not what you want in your case. You should probably use AlarmManager and set an alarm that starts your Service every minute. When your Service starts, it should create a background thread that contacts your server and checks for news. If there is no news it can just go away. If there is new news, it can either start your Activity to inform the user, or it can send a broadcast Intent which your Activity will see (if it is running),or it could create a Notification which the user can then open whenever he wants to. You need to figure out how you want to determine when the app should stop checking the server. Maybe the user should tell you that he isn't interested anymore, or maybe the Service can recognize that the app isn't running anymore (or hasn't been looked at in more than X hours or whatever). There are lots of ways to do this and it depends on your requirements.

What is the difference between an IntentService and a Service? [duplicate]

This question already has answers here:
Service vs IntentService in the Android platform
(11 answers)
Closed 6 years ago.
Can you please help me understand what the difference between an IntentService and a Service is?
Service is a base class of service implementation. Service runs on the application's main thread which may reduce the application performance. Thus, IntentService, which is a direct subclass of Service is available to make things easier.
The IntentService is used to perform a certain task in the background. Once done, the instance of IntentService terminates itself automatically. Examples for its usage would be to download a certain resource from the Internet.
Differences
Service class uses the application's main thread, while IntentService creates a worker thread and uses that thread to run the service.
IntentService creates a queue that passes one intent at a time to onHandleIntent(). Thus, implementing a multi-thread should be made by extending Service class directly.
Service class needs a manual stop using stopSelf(). Meanwhile, IntentService automatically stops itself when it finishes execution.
IntentService implements onBind() that returns null. This means that the IntentService can not be bound by default.
IntentService implements onStartCommand() that sends Intent to queue and to onHandleIntent().
In brief, there are only two things to do to use IntentService. Firstly, to implement the constructor. And secondly, to implement onHandleIntent(). For other callback methods, the super is needed to be called so that it can be tracked properly.
In short, a Service is a broader implementation for the developer to set up background operations, while an IntentService is useful for "fire and forget" operations, taking care of background Thread creation and cleanup.
From the docs:
Service
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
IntentService
Service is a base class for IntentService Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Refer this doc - http://developer.android.com/reference/android/app/IntentService.html
service: It runs in the background on your system. For example,
If you went to a hotel and you give your order for a soup to a server
The server gets your order and sends to chef
You don't know how the soup is made in the kitchen and what processes are required for making the soup
Once your order is ready, the server brings you the soup.
background process: chef making soup
IntentService:- it's consecutive service.. (i.e) when you order many food items at a time to server but the server delivers those items one by one and not deliver them all at once.
See Tejas Lagvankar's post about this subject.
Below are some key differences between Service and IntentService and other components.
Service
Task with no UI,but should not use for long Task. Use Thread within service for long Task
Invoke by onStartService()
Triggered from any Thread
Runs On Main Thread
May block main(UI) thread
IntentService
Long task usually no communication with main thread if communication is needed then it is done by Handler or broadcast
Invoke via Intent
triggered from Main Thread (Intent is received on main Thread and worker thread is spawned)
Runs on separate thread
We can't run task in parallel and multiple intents are Queued on the same worker thread.
Service runs actually in the same thread of your app; when you extends Service, you must manually spawn new threads to run CPU blocking operations.
vs
IntentService is a subclass of Service which spawns a thread to do background work from there(No need to create a new thread to do CPU blocking operations).
Service: Works in the main thread so it will cause an ANR (Android Not Responding) after a few seconds.
IntentService: Service with another background thread working separately to do something without interacting with the main thread.
Intent service is child of Service
IntentService: If you want to download a bunch of images at the start of opening your app. It's a one-time process and can clean itself up once everything is downloaded.
Service: A Service which will constantly be used to communicate between your app and back-end with web API calls. Even if it is finished with its current task, you still want it to be around a few minutes later, for more communication

Share a thread between different activities

I'm about to develop an application for Android.
I need to continuously run an update thread that executes a task in a given interval. And this thread needs to be shared between activities.
I would also like to notify the active Activity when the thread executes a task.
In iOS I would execute a thread from the AppDelegate and then send notifications, but how do I achieve this with the Android SDK?
I'd say create a Service that does the work for you. When it starts or finishes (or at any point you want), you can send a custom broadcast intent to indicate all parties that your service has passed this point. See Intents.
If you want to start this Service periodically, also have a look at the AlarmManager. That allows you send a broadcast intent periodically - in this case the intent that starts the service.
Also note that it's usually wiser to to terminate a service via stopSelf() when it's work is done. Run it again via intent when needed. Keeping it alive all the time isn't a good idea when it comes to battery life.
Make a service and implement a thread with infinite loop and from there you can do your job....to update data in activity you can make a static method and you can call it from there with appropriate arguments....

Categories

Resources