54

I have been reading around on internet connectivity with Android and noticed there are different ways to handle this i.e. AsyncTask and IntentService. However, I'm still not sure which one to use. My application is basically a location/trails finder with Google Maps. My internet connectivity will be used to find the nearest trails within a certain radius of the map. So, every time a user moves or swipes the map to a new location then it will update with the nearest trails. It will also add a new trail, and allow the user to rate a trail.

Will AsyncTask suffice for this or should I use IntentService?

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Johnathan Au
  • 5,244
  • 18
  • 70
  • 128

8 Answers8

59

They can be used very differently for different purposes.

AsyncTask is a handy threading utility that can be used if you need to constantly tell the user something or periodically perform operations on the main thread. It offers a lot of fine-grain control, and because of it's nature is very easy to work with in the Activity whereas an IntentService generally requires using the BroadcastReceiver or IBinder framework.

IntentService can be used very much like an AsyncTask, but it's purpose is meant for background downloading, uploading, or other blocking operations that don't need user interaction or main thread. For example, if you want to download and cache maps, you may want to call an IntentService so the user doesn't have to be looking at the app for it to download. Likewise, if you're sending data to your server, an IntentService is extremely helpful in this regard because you can start and forget. The user can, say, type a comment in your app then press "send". "Send" will launch the IntentService which gets the comment and send it off in to your server on a background thread. The user could press "send" and leave the app immediately and the comment will, eventually, still reach your servers (assuming no errors of course). If you did this with an AsyncTask in your Activity on the other hand, the system could kill off your process in the middle of your exchange and it may-or-may not go through.

Generally speaking, neither are meant for long running applications. They're meant for short, one-off operations. They could be used for permanent, or long-running actions but it's not recommended.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • 4
    What should be used for the long-running operations than? – roiberg Mar 20 '13 at 13:41
  • 2
    A generic Java Thread if it's blocking. You can put it in an Activity or Service depending on the need. Control the lifecycle using the lifecycle methods to ensure they don't run when they're not supposed to. – DeeV Mar 20 '13 at 13:45
  • -1: `...An IntentService generally requires manipulating the BroadcastReceiver framework.` No, it doesn't. Please see @Joe Malin's answer: http://stackoverflow.com/a/15168625/109941? – Jim G. Mar 08 '14 at 19:56
  • 2
    That was meant in comparison to Asynctask which would use callbacks. You don't have to use BroadcastReceivers for anything, but that is an approach if you want it to report back to the Activity. Another approach would be binding since it is at it's core a normal Service. – DeeV Mar 09 '14 at 03:25
  • You *can* use IntentService for long-running operations. I use it (correctly) for perpetual operations. – ban-geoengineering Jan 22 '16 at 10:19
  • @ban-geoengineering Wouldn't that mean you'd need a separate Service running for each operation rather than one Service that runs them in parallel? – DeeV Jan 22 '16 at 15:07
  • No sure, but as stated in the IntentService documentation: "All requests are handled on a single worker thread -- **they may take as long as necessary (and will not block the application's main loop)**, but only one request will be processed at a time." http://developer.android.com/reference/android/app/IntentService.html – ban-geoengineering Jan 22 '16 at 15:49
  • @ban-geoengineering Right. So if you wanted to do two long-running processes, you'd need two running services. The same if you had 5, 8, 10 or more. Although I guess for most cases, it's not a big deal. – DeeV Jan 22 '16 at 16:11
52

You should use an AsyncTask for short repetitive tasks that are tightly bound to an activity, like what you're currently trying to do. IntentService are more geared towards scheduled tasks (repetitive or not) that should run on the background, independent of your activity.

ebarrenechea
  • 3,775
  • 1
  • 31
  • 37
  • Thank you for your answer. Can you give me an example of a task that would use IntentService? – Johnathan Au Mar 01 '13 at 21:34
  • 3
    Suppose you save trails for a given region on your app (like "favourites" or similar). If you want to keep them up-to-date then just set up an `IntentService` that would run every day and check for changes on those regions. – ebarrenechea Mar 01 '13 at 21:42
  • Ah, I see. So I guess it's like Facebook or Gmail notifications on our phones? – Johnathan Au Mar 01 '13 at 21:44
  • 3
    Pretty much, although I'm fairly certain those use push notifications, which are a different thing altogether. It would be like the email application with IMAP/POP3 that checks for emails every x minutes. – ebarrenechea Mar 01 '13 at 21:48
  • This is wrong information, `IntenetService` cannot run independently of your application, `Service` can. – Kanwal Sarwara May 05 '13 at 13:51
  • @Sarwara , What do you mean ? – MSaudi Feb 25 '14 at 07:53
  • 1
    comment says: "IntentService are more geared towards scheduled tasks (repetitive or not) that should run on the background, independent of your activity." But IntentService cannot run if your application is not running, If you want something to run even when application is off, you need Service, not IntentService. – Kanwal Sarwara Feb 26 '14 at 11:29
  • I do this in some apps: When the app is started I launch an IntentService to update the local data if needed (time since last update , WIFI available etc). The Application always displays what is stored locally. When new data is available I use a LocalBroadcastManager to notify the application and it refreshes its views (mostly calls to notifyDataSetChanged on adapter) In this scenario, an IntentService is a lot better than an AsyncTask Whatever activity that is currently active when data is ready will be notified and can chose to act on the new data or not. – Glenn Bech Jul 18 '15 at 17:53
  • @Sarwara Please, and how can the activity get result , lets say i sent a message and i need to know if the message has been delivered or not? – Paul Okeke Jul 21 '15 at 09:32
  • AsyncTask used only for few seconds operations – Eslam Sameh Ahmed Aug 11 '15 at 00:46
22

AsyncTask doesn't play well with configuration changes or other things that restart the Activity.

IntentService is good for a something that should always be available, regardless of how long it takes to do its work. I prefer IntentService in most cases because AsyncTask is so much more dependent on Activity state.

Some notes:

  • AsyncTask is best for quick tasks that should go right back to the UI, but it can be used in a variety of situations.
  • The statement "periodically perform operations on the main thread" is vague. AsyncTask spawns a new background thread that is different from the main thread, and does its work on the new thread. Thus the name AsyncTask.
  • An IntentService doesn't require "manipulating" the BroadcastReceiver framework. All you need to do is send a local broadcast Intent, and detect it in your Activity. Whether this is harder to do than an AsyncTask, I don't know.
  • IntentService is meant to do long-running tasks, which it does in the background.
  • AsyncTaskLoader is OK to use, but it's meant to be the base class for CursorLoader, etc. If you want to refresh "nearby" trails when users move to a new location, an IntentService is probably better.

Don't forget to check for connectivity before trying to update location.

Joe Malin
  • 8,621
  • 1
  • 23
  • 18
8

AsyncTasks are very tightly bound to Activitys and can often cause leaked window errors if you navigate away from the Activity that created the AsyncTask. But they are great for showing a ProgressBar because you can quickly update the progress percentage.

IntentServices are cleaner and safer. They are more difficult to implement when you are a beginner Android developer, but once you learn how to start them and handle them you will probably never go back to AsyncTasks!

IntentServices also allow for a more modular design in your app. I typically create a separate class for all my IntentServices, but for AsyncTasks I create them as an Activity inner class. If I were to separate out an AsyncTask from an Activity, I would have to pass in the Activity Context and View objects in the AsyncTask constructor which can be messy.

Lou Morda
  • 5,078
  • 2
  • 44
  • 49
  • To overcome the messy problem, couldn't you add an inner Interface to your AsyncTask class. The interface would contain the callback method(s) for the activity to implement? – ban-geoengineering Jan 22 '16 at 10:15
6

As mentioned above AsyncTask will solve your problem.

But Keep in mind that AsyncTask has an important weakness: it doesn't handle well Activity "refresh" (eg during rotation). It may be a problem if, e.g., user rotate the phone while your AsyncTask is still loading stuff. If this is indeed a problem for you I recommend AsyncTaskLoader:

http://developer.android.com/reference/android/content/AsyncTaskLoader.html

ivan.aguirre
  • 500
  • 4
  • 11
4

AsyncTask and IntentService have many same

  • Can execute task in worker thread
  • Can run in background
  • Keep running till task finished event the activity which started it is destroyed
  • Can notify to update UI during task running or after task finish
    • For AsyncTask we often use onProgressUpdate, onPostExecute or if you want you can use BroadcastReceiver
    • For IntentService we use BroadcastReceiver

Different

1) Send task while running or after running finish

Example we have a task is: download file from server base on fileName.

Using AsyncTask

If we one instance of AsyncTask, during execute downloading file A we cannot execute download file B AsyncTask (since we get java.lang.IllegalStateException: Cannot execute task: the task is already running.). Also after downloading file A finished, we can not execute download file B (since we get java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once).
To download file B during or after download file A, we need to create new instance of AsyncTask.
=> To download file A and file B, we need 2 instance of AsyncTask => 2 worker thread created

Using IntentService

During download file A, we can sent intent to download file B => after download file A finished it will auto start download file B => don't need new instance, don't need new worker thread.

If we sent intent to download file B after download file A finished? After download file A finished, IntentSevice will destroyed (because there is no more task). Therefore, when start download file B, new instance of Service is created however no new thread created (service keep using only 1 worker thread which name is defined in IntentSevice constructor

2) Implement AsyncTask is easier than IntentService

USING
We will see that AsyncTask and IntentService have many same so in most case we can use AsyncTask or IntentService. However

  • I often use AsyncTask for some task that start, finish, interact with UI in 1 Activity
  • I often use IntentService for some task that can start/finish and interact or don't interact with UI from any Activity

This answer is base on my test. Please correct me if I am wrong. Hope it help.

Linh
  • 57,942
  • 23
  • 262
  • 279
0

In short, AsyncTask is meant for short tasks that have to communicate with main thread. IntentService is meant for long tasks that don't have to communicate with main thread.

For more info, check these links

http://www.onsandroid.com/2011/12/difference-between-android.html

https://medium.com/@skidanolegs/asynctask-vs-intentservice-1-example-without-code-5250bea6bdae

https://android.jlelse.eu/using-intentservice-vs-asynctask-in-android-2fec1b853ff4

Hasan El-Hefnawy
  • 1,249
  • 1
  • 14
  • 20
-1

I agree with @DeeV and @ebarrenechea about Intent service in part that you should use it for task that are not tight bound with Activity like uploading some data to server or storing data from server to database.

But starting from Android 3.0 there were introduced Loaders API Which should replace AsyncTask. So for example for loading list which you should display in Activity is better to use Loader which is designed to handle well all the configuration changes and Activity Life-cycle.

Vogella loader tutorial

Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67
  • Are you sure Loader should be used for server work? I've never heard of that before and I didn't see anything in the docs or tutorial you linked to that suggested that. – ban-geoengineering Jan 22 '16 at 10:27