I have a very intensive task, where I parse around 100 json files stored in assets and create a tree structure from that..
Then i update the UI based on resulted tree.l
Currently, I am using AsyncTask to do this job.
But, I am looking for better, efficient and clean way to do this. Any libraries or any other in-built functionality which i should use ?
I would go with an IntentService here. It already provides a background thread and it will stop itself once it's done. If you need to update the UI after that, you can use a Handler or a BroadcastReceiver.
EDIT
You can still use an AsyncTask but still, start it from a Service. AsyncTask is just a wrapper around java thread, it's not an Android component. You have to start it from some context, in this case it's either Activity or Service.
If you start it from Activity then your long-running operation will depend on the UI which in most cases will cause a memory leak. Service is a background component which runs independently from the UI. Also, Service will increase your app's process priority so that it less likely to be killed by Android when the system is running on low memory.
If you use IntentService, you don't need an AsyncTask anymore, it runs on the backround thread already. If you want to go with a regular Service, you will need to implement background execution on your own. Via java thread or async task for example.
If this is heavy and long running use a Service and communicate using broadcast receivers.
Related
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?
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.
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.
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.
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.
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
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.
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
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
I just read Android Architecture Tutorial: Developing an App with a Background Service (using IPC). It is basically
Have a service run in separate process.
A repeated timer event will occur in the service.
Within the timer event handler, it will perform networking to retrieve tweet, and inform all the listener attached to it. Listeners are attached to it through IPC.
I can see there are 2 major characteristics with this approach.
Tweet retrieving action run within separate process.
It always run, even the main activity has quit.
However, if "It always run" is not my requirement. I want everything to stop when I quit my main Activity.
Will it be better, if I use AsyncTask (Or Timer) within my main Activity, to perform tweet retrieving action? Everything will be run within single process. No more using Service.
Using AsyncTask (Or Timer), seems simpler. We no longer need to deal with IPC.
Or, using Service approach might be better? Am I missing some goodies provided by Service?
Using service is a better approach as it will allow you to perform the polling independent from the application flow.
As it is a task where no user interaction is required and it has to be done in the background without disturbing the main UI of application and whatever the user is doing, a service is an ideal candidate for its implementation.
It is possible to bind the service with the application in such a way that when the main application terminates, it will also turn off the service.
I would take the view that a TimerTask can be set to execute and repeat at a given interval, Timers run on a separate thread so all this work would occur in the background without disturbing the UI. It would be easy for you to trigger an update within your app when the TimerTask completes and update the UI when you want.
When you exit the app it's a simple case of calling cancel() on your Timer and the purging all the tasks with purge().
Nice and easy and you don't need to implement IPC, which can be very fiddly to get right.
EDIT
Using AsyncTask you can do pretty much exactly the same thing but you'll have to manually schedule the next run. I have used both solutions in the past and found them to work equally well so it's all down to your preference.
At first you have to know, that a service isn't a Thread. If a activity binds a Service and runs as a Deamon, but a ASynchTask is another thread.
ASynchTask's are designed for doing some work which should not running on UI-Thread (for example processing some larger calculations)
Services are designed to run permanantly on Background.
If you want to permanantly check for new tweets, even if your activity is stopped or paused, you should use a Service, which checks into an own thread for new data.
TimerTask are good old java style implementations which run on their own thread.
You can used them for processing some data, but you'll have some problems to manipulation UI. If you want to be it on propper "AndroidWay", use a Handler instead of TimerTask.
First of all, I know the tutorial you are following...I've followed that tutorial myself while trying to learn IPC. One thing you need to know is, The Android docs explicitly say,
Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
If at all possible, you should just bind to the service.
Also, you must consider, do you really need a service? Consider that the Android Twitter app doesn't even refresh tweets for you, its on an as needed basis. Polling can be battery intensive, so you must consider if this is really necessary.
Also, will you be using these tweets from multiple activities? If so it would be nice to not duplicate the code in multiple places. So maybe you do want a service in this case.
Other than that, I would recommend that you start simple (Async task with a timer to update it), and move to a service if you think you need it.
When something asynchronous needs to be done it is often recommended to put this in a service, maybe an intent service. Great. However, it is also not recommended to startup an activity from a service ... So when asynchronous response comes back inside the service perhaps the user is on a different screen. Then their is the whole aspect of binding to services ... One is left wondering which way is better and why? I mean services are cool but there is the binding to service call and there is also the issue that services should not have callbacks into activities. So which way is better. What is the criteria for using an AsyncTask vs. a Service to do async work? Also there is requestForResult() option too ...
The criterias are basically,
Do you need to update some data regularly or continue some task (android gives an example of a music player where the music continues even when no activities are visible) even when your application activities no longer run? Use service here.
Do you have a need where your data or some task needs to be run by multiple applications? In such case the applications need to bind to your service and access the info.
Do you have a case there is IPC involved? Use a service.
Do you have a case where all u need to do is do a heavy task like downloading data, some kick ass algorithm which takes time? Do all heavy tasks in a background thread and update the UI once completed. use an AsyncTask.
Asynctask is simple. Used mostly in your activities to do heavy tasks in a separate thread to avoid ANR.
Services on the other hand is used to do tasks which needs to run even when your app is not running, other app needs to bind to update data, you need the updated data before displaying your activity.
I am sure there are more criterias, but these are just a few that just came to me.
Why do I read in the answer to most questions here a lot about AsyncTask and Loaders but nothing about Services? Are Services just not known very well or are they deprecated or have some bad attributes or something? What are the differences?
(By the way, I know that there are other threads about it, but none really states clear differences that help a developer to easily decide if he is better off using the one or the other for an actual problem.)
In some cases it is possible to accomplish the same task with either an AsyncTask or a Service however usually one is better suited to a task than the other.
AsyncTasks are designed for once-off time-consuming tasks that cannot be run of the UI thread. A common example is fetching/processing data when a button is pressed.
Services are designed to be continually running in the background. In the example above of fetching data when a button is pressed, you could start a service, let it fetch the data, and then stop it, but this is inefficient. It is far faster to use an AsyncTask that will run once, return the data, and be done.
If you need to be continually doing something in the background, though, a Service is your best bet. Examples of this include playing music, continually checking for new data, etc.
Also, as Sherif already said, services do not necessarily run off of the UI thread.
For the most part, Services are for when you want to run code even when your application's Activity isn't open. AsyncTasks are designed to make executing code off of the UI thread incredibly simple.
Services are completely different: Services are not threads!
Your Activity binds to a service and the service contains some functions that when called, blocks the calling thread. Your service might be used to change temperature from Celsius to Degrees. Any activity that binds can get this service.
However AsyncTask is a Thread that does some work in the background and at the same time has the ability to report results back to the calling thread.
Just a thought: A service may have a AsyncTask object!
Service is one of the components of the Android framework, which does not require UI to execute, which mean even when the app is not actively used by the user, you can perform some operation with service. That doesn't mean service will run in a separate thread, but it runs in main thread and operation can be performed in a separate thread when needed.
Examples usages are playing music in background, syncing data with server in backgroud without user interaction etc
AsyncTask on other hand is used for UI blocking tasks to be performed on a separate thread. It is same like creating a new thread and doing the task when all the tasks of creating and maintaining the threads and send back result to main thread are taken care by the AsyncTask
Example usage are fetching data from server, CRUD operations on content resolver etc
Service and asynctasks are almost doing the same thing,almost.using service or a asynctask depends on what is your requirement is.
as a example if you want to load data to a listview from a server after hitting some button or changing screen you better go with a asynctask.it runs parallel with main ui thread (runs in background).for run asynctack activity or your app should on main UI thread.after exit from the app there is no asynctask.
But services are not like that, once you start a service it can run after you exit from the app, unless you are stop the service.like i said it depends on your requirement.if you want to keep checking data receiving or check network state continuously you better go with service.
happy coding.
In few cases, you can achieve same functionality using both. Unlike Async Task, service has it's own life cycle and inherits Context (Service is more robust than an Async Task). Service can run even if you have exited the app. If you want to do something even after app closing and also need the context variable, you will go for Service.
Example: If you want to play a music and you don't want to pause if user leaves the app, you will definitely go for Service.
Comparison of a local, in-process, base class Service✱ to an AsyncTask:
✱ (This answer does not address exported services, or any service that runs in a process different from that of the client, since the expected use cases differ substantially from those of an AsyncTask. Also, in the interest of brevity, the nature of certain specialized Service subclasses (e.g., IntentService, JobService) will be ignored here.)
Process Lifetime
A Service represents, to the OS, "an application's desire to perform a longer-running operation while not interacting with the user" [ref].
While you have a Service running, Android understands that you don't want your process to be killed. This is also true whenever you have an Activity onscreen, and it is especially true when you are running a foreground service. (When all your application components go away, Android thinks, "Oh, now is a good time to kill this app, so I can free up resources".)
Also, depending on the last return value from Service.onCreate(), Android can attempt to "revive" apps/services that were killed due to resource pressure [ref].
AsyncTasks don't do any of that. It doesn't matter how many background threads you have running, or how hard they are working: Android will not keep your app alive just because your app is using the CPU. It has to have some way of knowing that your app still has work to do; that's why Services are registered with the OS, and AsyncTasks aren't.
Multithreading
AsyncTasks are all about creating a background thread on which to do work, and then presenting the result of that work to the UI thread in a threadsafe manner.
Each new AsyncTask execution generally results in more concurrency (more threads), subject to the limitations of the AsyncTasks's thread-pool [ref].
Service methods, on the other hand, are always invoked on the UI thread [ref]. This applies to onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), etc. So, in some sense, Services don't "run" in the background. Once they start up (onCreate()), they just kinda "sit" there -- until it's time to clean up, execute an onStartCommand(), etc.
In other words, adding additional Services does not result in more concurrency. Service methods are not a good place to do large amounts of work, because they run on the UI thread.
Of course, you can extend Service, add your own methods, and call them from any thread you want. But if you do that, the responsibility for thread safety lies with you -- not the framework.
If you want to add a background thread (or some other sort of worker) to your Service, you are free to do so. You could start a background thread/AsyncTask in Service.onCreate(), for example. But not all use cases require this. For example:
You may wish to keep a Service running so you can continue getting location updates in the "background" (meaning, without necessarily having any Activities onscreen).
Or, you may want to keep your app alive just so you can keep an "implicit" BroadcastReceiver registered on a long-term basis (after API 26, you can't always do this via the manifest, so you have to register at runtime instead [ref]).
Neither of these use cases require a great deal of CPU activity; they just require that the app not be killed.
As Workers
Services are not task-oriented. They are not set up to "perform a task" and "deliver a result", like AsyncTasks are. Services do not solve any thread-safety problems (notwithstanding the fact that all methods execute on a single thread). AsyncTasks, on the other hand, handle that complexity for you.
Note that AsyncTask is slated for deprecation. But that doesn't mean your should replace your AsyncTasks with Services! (If you have learned anything from this answer, that much should be clear.)
TL;DR
Services are mostly there to "exist". They are like an off-screen Activity, providing a reason for the app to stay alive, while other components take care of doing the "work". AsyncTasks do "work", but they will not, in and of themselves, keep a process alive.
Is there any difference between AsyncSync being fired up from Activity or IntentService?
I'm building an app which downloads and uploads files via http. I use custom notification layout with progress bar for each transfer.
I choose between doing transfers in parallel or putting them into queue (which option would you recommend?).
For the option with queue I use an IntentService, so Android framework takes care of putting tasks into a queue for me.
For having them in parallel I use AsyncTasks. But I fire them up from IntentService (could be Service as well) - is there any point doing so? IntentService is terminated right after it executes AsyncTask, so the AsyncTask runs without any "parent".
What if I fired up those AsyncTask from Activity, go to the homescreen and system decided to close this Activity? Can it do that? Will the AsyncTask survive it?
What would be the preferred approach for this case?
AsyncTask isn't really appropriate for things where you're concerned about surviving outside the lifecycle of a component (if you need to message back to that component). If you're going to the extent of having a service, I wouldn't even bother with AsyncTasks. As far as parallel or queue, that really depends on a lot of different variables, but I certainly wouldn't make it completely parallel for any number of downloads/uploads. I'd set some limit on the max number of concurrent transfers.
There's no point in using IntentService for parallel exeuction--you've noted the problem with that already. You're getting into territory which is not really covered by the Android API. AsyncTask and IntentService are nice abstractions that make several scenarios easy, but parallel execution of many many tasks is not one of them. It's probably best to use some of the Java threading/concurrency classes. Take a look at ThreadPoolExecutor.
First your easy questions, an AsyncTask will survive being in the background as long as the parent application is not killed. Starting it from an Activity will tell the system that it can be killed if memory pressure requires it. The system also does not consider it having a long running process that may be interrupted.
The dev guide Services has a great info box under its "The Basics" heading about whether you should use a Service or Activity. Activities get none of the memory pressure consideration that Services get or a restart after a kill, when system resources become available again.
If you wanted me to make the call for you, use the IntentService. Whether to run the downloads in parallel or series or some combination is a tough call because you must consider the network (Wifi or Cellular), file size, and other system resources.