Hey guys, I could only find 1 thread on this, and it didn't really answer my question, so I'm asking for myself.
My application is downloading and parsing an rss file, and I've obviously decided to do this in a background task. I chose AsyncTask, and I'm trying to get it to start the download and then bring up the list view for the rss feed. From there I'd like the AsyncTask from the other activity to pass the now parsed information to the new list view activity as it loads it. I can't figure out how to pass a reference to my AsyncTask object to my new activity without implementing parcelable and adding it to the bundle which would be a huge mess I think. Is there a better way to do this?
I've also seen other people recommend starting a service. What would be the advantages to doing it this way? Thanks!
~Scott
This is exactly the case for using a service. An AsyncTask is for doing things on a UI thread (a convenience class really).
What you are doing should go on in a service, because you don't necessarily care about the UI thread since you are not going to be displaying in the same activity.
Here is how you should go about doing this:
1) create a service and do the processing of the RSS feed
2) inside the service you should store your results in a database with the ContentResolver
3) Have your ListAdapter in your ListActivity listen for changes on the same CONTENT_URI as your service is updating. This will automatically update your list as the rows get added or deleted, without any ANRs since it's all on the background thread
Some other advantages is that you can sync in the background without having your UI to be open at all. This could be very useful for a RSS application since you don't always want to wait for a user to initiate a sync.
Call your async task and download the RSS feed in a static ArrayList and use that arrayList to update the first activity by using custom adapter.Then do the same thing in other classes where you require this Rss feed.
Related
I have an activity where the user enters a value in an EditText and I search a string array that I have defined in a xml file for a match. Each time the user changes the text I look for a match. When I start this activity I load the string array resource.
Should the loading of the array and the match finding occur in a background thread?
From what I understand I can use an AsyncTask which I am familiar with or a IntentService which I have no experience with. Would IntentService be overkill? What is ideal for this operation?
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.
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.
You should use AutoCompleteTextView and ContentProvider to do your implementation. Save your string array in database and access them by Cursor to popup and show in AutoCompleteTextView. There is an example available in the official document.
I have my MainActivity which gives the user a selection of pages to open, all of which involve downloading some data from the internet and displaying it. To save the user waiting when they choose their page I've made an AsyncTask as a subclass of MainActivity which produces an object DATAwhen the download is complete.
How would I pass DATA on to the SecondActivity in the following circumstances:
The user chooses the SecondActivity before the AsyncTask download has completed.
The download completes before the user chooses the SecondActivity.
the AsyncTask doesn't have to be a sub-class of MainActivity its just been tidy to do it that way so far,
thanks for the help!
Here's one way to do this:
Create a reference to your data in your Application. The Android Application is a good place to store global data. Next, populate the data via your AsyncTask (Watch out for the pitfalls of using an AsyncTask). You can now access your data via a call similar to this: ((MyApplication)getApplication).mydata
As you mentioned, two scenarios can come up. Either the data has been populated, or not. To handle this, use an observer that observes changes to the data. Have SecondActivity register as an observer when the data is null. When the data is available your SecondActivity's update method will get called and you can do whatever you please with it. Finally, make sure to unregister from being an observer.
Hope this helps.
Passing information directly between activities works only if it is Parcellable (via Intent). Almost anything could be made Parcellable but it is not always a good idea especially when the amount of data is large.
The next problem is that your AsyncTask most likely keeps the Context of your first activity alive when it is running longer than the activity lasts. Activity instances are quite often recreated when you rotate the device and naive implementations tend to start another asynctask in the new instance and end up with multiple tasks that download the same data. You would need to pass the reference of a running task between instances of the same Activity.
The simplest solution is probably to create a singleton (or a Service) accessible from both activities that hosts the AsyncTask & loads the data. If it requires a Context use getApplicationContext() since that's safe to use outside the lifetime of Activites.
Activities could register themselves as listeners for "data loaded" events while they are active.
I've recently struggled with AsyncTask and had difficulty having the UI behave while the task was running in the background. While there are comments around that services aren't really appropriate for the sort of thing you're describing, I've found them much easier to work with. You might check intentService as a middle ground. Good tut's can be found here and, specifically concerning intentService, here.
This is somewhat design specific question but I am looking for right advice.
In my app I have 6 pages A,B,C... each of which will download data from server and display it. In this case among below mentioned approaches which one will be good.
1.For each A,B,C write inner asynctask class
2.write separate asyntasks like asyntaskA,asyntskB etc for each of these activities
3. write a single asynctask and route request of each activity through a requestcontroller class which creates instance of asyctask by passing context,url parameters
If the second approach is taken, is it possible to run one Activity and another Activity in onpause state while its asynctask still running?
In each page, if you are doing the same kind of operation (As in this case, downloading data and displaying it), you need not write separate AsyncTask classes. Just create as much instances as you need and call the execute() method. AsyncTask class will handle this in thread safe way.
Second part of your question is bit unclear, but if you meant switching between activities, it is possible with multiple instances of a single AsyncTask. You'll need to save and restore the activity states.
If the operation you performing is time consuming, say more than few seconds, it's not safe using an AsyncTask. The better option will be a Service.
There's no problem with multiple AsyncTasks. In one of my apps I have a grid-view with images and there's an AsyncTask for every image loading and generating a thumbnail image. They all run in parallel quite nicely.
If I need to asynchronously load some data via HTTP (or whatever) in order to update the UI, I have a few options when writing an Android application (among many others that I'm sure I missed):
Use a regular thread and a handler to update the UI.
AsyncTask
Use and IntentService, and use either a callback or broadcast the results via an Intent.
Using Loaders.
From what I understand, an IntentService is not tied to an Activity's lifecycle, so any changes to orientation, etc, will not impact the retrieval of data. Where this is not the case for an AsyncTask or thread fired off within an Activity.
The reason for the question, is that I just recently read about Loaders, and am confused as to their application. They seem to be more closely tied to a data source, where if the data source changes, then "transparently" everything is handled appropriately. Loaders also appear to be tolerant to configuration/orientation changes (I believe).
I've been currently using an IntentService to make RESTful service calls, and broadcasting the results to be received by appropriate Activities.
I'm assuming I could write an HTTP based Loader, but I'm not sure if this is the best use of this mechanism.
What are the advantages/disadvantages to using one of the async data loading methods over any other?
All of these mechanisms are simply options. There's no such thing as a one size fits all tool and so all of these different methods of completing the same task is a way to cover as many use cases as possible.
Ultimately, it's up to you to decide which method makes more sense for your scenario. But for a sort of generic explanation of what you should use...
Regular thread and a handler - Why when there are other, simpler, options?
AsyncTask - Since an AsyncTask will almost always depend on an Activity, use this when you need to load data asynchronously and you are 100% certain of how long it may take. Example: Executing an SQLite query.
IntentService/Service - Services are not bound to an Activity like an AsyncTask is, therefore, they are perfect for scenarios in which you may not know how long it will take to complete. Example: Downloading data from a web API and updating a database.
Loaders - Loaders are aimed at simplifying the process of loading data and populating it into UI. The nature of Loaders sort of assumes that the data you will be loading will be presented to the user as a list of some sort. Example: Downloading data and populating it into a ListView
I have an Activity that displays a text based on data pulled from MySQL server. The problem is that the Activity won't load until data is pulled, which sometimes takes some long seconds or even doesn't load at all, and in the meantime the users gets a black screen.
I tried to pass the mission of getting the data from the server to a service, but also it waits for pulling the data and only then shows the layout of the Activity.
I also tried to make an activity with fixed text and then call the Activity that pulls the data from the server, but still the program wait for the data.
Can you think on a creative solution for it? or maybe a non-creative one as well :)
you can use asynctask for this:
http://developer.android.com/reference/android/os/AsyncTask.html
or you can show a waiting dialog to user until you get your data(do it in separate thread).....
or you can implement a splash screen and there you can fetch data.....
You need to do it inside another thread. Try using AsyncTask class.
The delay is probably due to the call to fetch the data being done on the main thread, also called the UI thread. Processes which take any significant amount of time, and by that I mean even a second or two should be done in a seperate thread. Android provides a class called AsyncTask to help make threading painless.
You mention you tried a service but did you take a look at an IntentService? (Can't link it yet but it's on d.android.com.) I like using them for these kind of tasks cause they handle the threading for you (like an AsyncTask) and it separates concerns better. The IntentService then sends a broadcast message that the activity picks up indicating that the data is available or not. Store the data locally in a sqlite db or as a json/xml file.