I am working on an application that Looks similar to the Google Play App (swipe view with gridviews inside the fragments, in addition data in the gridview [image + text] is retrieved from a remote server).
My problem is with background tasks. I can’t decide what to use for retrieval of data from the internet. Mainly I am trying to decide whether to use AsyncTask or manual threading.
Of course it would be easier to implement AsyncTask, but after some research I noticed that many people find it limiting.
In my particular case, I want to download data from the internet as Json Objects, parse them and display the data in the gridview. The gridview would have up to 30 items, each item contains a thumbnail and 3 textviews. In Android documentation, they say that AsyncTask is suitable for short operations (few seconds at most). Would filling up to 30 items be considered as a short operation?
I want the data to be fetched concurrently. Also I want to support Android phones from API 8 and above. I read that for different APIs AsyncTask behaves differently (serially or concurrently)
My question is: Is it appropriate to use AsyncTask for my app? Or do I have to do everything manually? Is ThreadPoolExecutor a 3rd way to do this? Is it easier than manual threading?
Any advice would be appreciated, I can't move forward in the implementation without deciding on this issue.
Thanks in Advance!
My understanding is that the comment about using AsyncTasks only for short operations is aimed more at not expecting the same views to be available when a long operation finishes. For example, if a user leaves the app and comes back or the current activity goes away for some reason. Typical ways around this would be to use a Service and start up a plain old Thread there, then send some message telling the current Activity to refresh when the operation is done.
The download and processing of your data is likely to be the longest operation. So I'd use that as a basis for whether this is short or long. If you don't care about persisting data at all and don't mind restarting downloads if a user leaves and comes back, you can just use an AsyncTask with very little thought.
If you are using a GridView, you should only ever be populating enough views to for just over the number displayed on the screen at one time.
I'd say that AsyncTask is fine in your situation assuming it's a few kilobytes of data and not megabytes or hundreds of kilobytes. Megs of data, I'd say move to a Service with a Thread. Hundreds of k, is a toss up.
Also, take a look into Loaders... if you want to see an alternative that is better for this kind of loading.
When attending DroidCon in London last year, a presentation brought to my attention why using AsyncTasks for loading data from the network is unreliable.
This presentation was about the RoboSpice library.
The site also has a very nice infographic explaining why exactly AsyncTasks are unreliable and what RoboSpice does to amend these problems.
Disclaimer:
I am in no way affiliated with RoboSpice, nor have I ever tried it. I was just impressed and convinced by their presentation that it's a tool worth trying.
Friend, I am working in a project exactly as you need, and to support API 8 and above you should use Asynctask to download anything or you will get a crash for API 15 and above, because it won't even let you run your app without AsyncTask even for short operations.
So as I almost did everything that you need and it is working very well for API 9 above, you should use Asynctask, I´ve implemented SherlockActionbar, EndlessAdapter and ViewPager all with AsyncTask, so go on, if you need more help just ask again later.
Related
I have been working on an android project that has a feed similar to Instagram/Facebook and I am trying to figure out the best strategy for consuming the data from my database.
Specifically I am wondering if I should query all the data at once (assume 50 records +) or if should I perform queries as the user scrolls -- grabbing so many records at a time. If the ladder, about how many posts/records should I get per query assuming the content/size is similar to that of a Facebook post.
I've spent a descent amount of time researching this issue and haven't come across anything so any suggestions would be much appreciated. I do apologize if this issue has already been addressed and if you could you just post the location of the answer that'll work too.
Thanks in advance!!
Fetching all the data can be too much at times and your app will have very slow response time, that why it's better to load some data at a time and just add it as you get it. In my opinion it's best to load 2 screens of data at a time, so try and see how many posts you can have in a screen and get x2 (if on one time you can see 5 posts, load 10 at a time) or load for example 10 at the first time and 5 each next time. This truly is your preference as I think.
If this is the method you want to use keep in mind that there are different screen sizes for android (from android wear to different sized mobile phones, tablets and smart tv-s) so try making different methods for each group if devices. You can maybe have an abstract class (or interface) with the method and have every other class for different size extend or implement (regarding of using class or interface) to make the code more well written, easier to change and reusable.
But all in all it's in your hands and you can make it by your liking. Hope this helps, and gives you some matter to wrap your head around.
I'am developing an application which is totally based on fetching data from web services.
In one activity I have to call almost 5 6 different web services which displays different information. This application is target v 2.3 to 4.x, as there are no network communication allowed on main ui thread so I am making 5 6 AsyncTask classes, because its post execute helps me a lot in displaying.
Now I am confused is this approach right or wrong, making 5 6 AsyncTask classes(can't reduce the number of web services or call in one AsyncTask because I have to check data again and again). Is this a good approach or should I change my pattern, and then switch to what approach.
Using this approach my application is working very nice and smooth on all devices.
I think that's a good pattern. It fits nicely into Object-Oriented design and each one performs it's own task.
If your web calls are all directly after each other, you could combine them into one huge AsyncTask if you really want to. That would definitely reduce the nice encapsulation you have now and would make it a lot harder for someone to maintain and debug down the line.
It sounds like what you have is good already, and if it's working well, why fix what's not broken.
I would assume that each ASyncTask class is an API request to the webservice, if so it is the right way of doing it. Any network operation should be done outside the UI thread.
There is also a better way of using ThreadPools to limit the number of Server requests you want to keep active at a time.
Are there any advantages of Loaders over Async task? Also, how to make loaders compatible for phones with Android froyo.
Edit:
The primary problem here is that I'm not using the native DB(SqlLite). Using the DB on development server. Obviously, I can't use CursorLoader any more. AsyncTaskLoader has no examples at all. If any, please do link.
Is it a better idea to load the data required onto the local DB and then query it using CursorLoader?
Yes, Loaders are more advantageous than AsyncTask as they take care of a lot of things that AsyncTask falls short of, miserably.
Screen Orientation changes are difficult in AsyncTask. I used to have such a problem, till I used an Activity Control class, which I used to retain while configuration changed. I can give you some code if you want to know how. The app used to crash, though, when you changed the orientation multiples times even before the entire data loaded. The secret here is not load a lot of data with your first thread and and finish your threading tasks as soon as possible. Even if it happens in the background, Android has a shabby way of dealing with threads. You never know when one of your tasks would be killed.
Even if you use a AsyncTaskLoader, makes sure that you use an Activity manager. This will help you in getting more control over the activites and AsyncTask.
Yes, it is compatible in all the old version of Android. You need to include the support library(Most of the times, this is included by default but its always nice to double check.)
For one, loaders are easier to code (they're almost built-in in Fragments).
Loaders (specifically CursorLoader) also handles your cursor for you (like the deprecated manageQuery).
Check out this link to read on how to use Loaders pre-Honeycomb.
There simpler to implement and take care of a lot of the life cycle management which previously had to be done "by hand" with AsyncTasks. See the answer to this question for further detail.
With regards to using them with Froyo, they're available via the compatibility library.
It seems no one is talking about the disadvantages of loaders! I'm currently working on a system that runs other services in the background.
What I have noticed is that as soon as a screen with a loader is resumed. The cursor used by the loader locks up the DB.
It may not be open to most people but getDatabaseWriter from sqlite is actually a synchronized method and hence the cursor used by the loader is never closed until the loader is reset or terminated thus locking up access to the DB.
I cannot recommend using a loader under these circumstances nor can I advice using a loader when your result set consists of less than 100 items which are static and never seem to change.
Another advantage with loaders is that they handle screen turn event gracefully whereas asynctask can give you trouble.
Biggest diff:
CursorLoader will update your UI's content as soon as its related ContentProvider changes its content(say through a Service), while AsyncTask will only update your UI when you tell it.
Currently I'm receiving a JSON from a server with updated information on a contact. Currently, I iterate through the JSON and do an update on my app on the phone, but for 2000 contacts, it takes up to 50 seconds(I used transactions too, b4 that it took 70 seconds). Is there a faster way to speed this up?
Well, just remember that it's 2,000 row updates, and on a handheld phone/tablet. It's not a high-powered server with an in-memory database. This stuff takes time. Unless you're doing something more than what you're saying, it doesn't sound like you're taking more steps than required (i.e. there's nothing to cut out in order to save time)
Often performance is just as much perception, as it is optimization. One way to deal with this reality is to simply return control of the UI to the user, making your app look snappy and responsive, while doing the contact updates in another thread in the background. That would give your app the appearance of being very fast, even though it still takes 50 seconds to complete all the updates.
Are you using Android's built-in JSON objects? If so, that may be the source of the performance problem. The first time I profiled my app, I was surprised to find that JSON parsing was causing the biggest performance hit (see also this post in the Android Developers Blog).
You should profile your code to find exactly what is taking the most processing power then perhaps you may be able to find a more efficient solution to your problem
Profiling on Android is done making a tracefile on view, then viewing it with Traceview.
See here for detailed information
What is the best approach from a performance perspective to show a ListView with contacts and their phone numbers?
Use CursorAdapter with the contacts cursor and make the phone numbers query when bindView is invoked for each row
Copy all the contacts and phone numbers to an in-memory array in a background thread and then show them with an ArrayAdapter.
Other solutions?
In my opinion a mix solution should be better. Why this? Because you don't know or it's suppose that in most of contexts you cannot know about how and how many contacts your application will need to list. An also how many contacts are stored in the phone. If we know both answers, surely we can take the most approach solution.
So I suggest you to first bring a fix number of contacts using an in-memory array in a background thread, for example the first 20. Also if you consider that your app will perform more than one request to this service.. it will be awesome to use a sort of caching. The worst approach should be to call again and again the contacts service.
Then for a request for contact #21 you can bring next 20 and so on.
So you can use the advantages of both worlds, and minimize the disadvantages too. Always depends on the application and the context that we are talking about.
I think this would depend on three factors:
How many contacts are we talking about here?
How much time does it take to load each contact? (E.g. do you have a very complicated view that needs to be inflated or do you fetch contact images/etc that requires any network I/O?)
How much contacts are showing to the user at once?
Your solution one would fit most of the cases though the second solution offers some advantages as well:
Solution 1:
Advantage:
Delayed view inflation in a "view as you go" can perform well when it's fast enough to inflate the views without any noticeable UI glitches.
Disadvantage:
If your contacts associate with a lot of data and requires some complicate inflation, you might notice a delay.
Less flexible and extensible comparing to solution 2. As discussed below.
Solution 2:
Advantage:
You have control of all the steps, so you can easily simulate it just as easy as one, but adding things might be easier: searches through whole memory, custom sorting through the array, etc. they work better when you have everything queried to an array that's already there. Or if you want to do custom loading later, or adding some more data regarding the contacts that require some more processing (say network I/O), it might be slightly easier than cursor adapter.
Disadvantage:
Execution: this is not the text-book way to do it. making things more custom will need you to handle all the threads well and handle the initial appearance well. Make sure it scales.
So yea, depending on what exactly are you are working on, choose the appropriate one.
I think http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/ will be an option. Where you can find all of the facility you want...
I think CursorAdapter is the best solution.
Also make sure you watch this video http://www.youtube.com/watch?v=wDBM6wVEO70
It talks about optimizations that in my opinion are necessary to make your list scroll smoothly.