currently I have an app that creates all sorts of different requests to Facebook and my server, and I was wondering if the best way to do this is implementing a different AsyncTask or using the same AsyncTask for all the different requests.
what do you think?
Here is a use-case for instance:
I send a Facebook connect request, when I get to onComplete, I get the users Information with FQL (has to be Asynchronous) , when the response comes back, the user's image is posted on the main view.
After this, the app sends a different request to the app's background server and gets a response.
I think you must decide it for yourself.
If you have lots of requests beware of the android's limitation of number of AsyncTasks. If you hit that limit your app will crash.
Also notice that if you assign many jobs to a single AsyncTask you could have a very long running task on the background.
You can also read this article -> The Hidden Pitfalls of AsyncTask.
I'd suggest to use concurrent AsyncTasks to ensure all the other requests are run in case one of them won't return an answer.
Related
I am a Java developer with no Android experience, and I am trying to quickly put an app together. It seems that what I would normally do in Java isn't helping.
At this stage, ease of implementation is more important than efficiency or style - I will sort the latter out when there is more time and I will have educated myself properly when it comes to Android.
People can use the app to ask for support, or offer it to those who need it. Asking for support posts a request with the details to the server, and that's done.
Now I would like the app to post an asynchronous request to the server, to be notified of outstanding support requests once a minute. I guess it's the same principle of WhatsApp checking if there is any new message on the server.
I tried doing that in a separate thread with an infinite loop which sleeps for 60 seconds but for some reasons that stops the UI from working.
From what I now understand, I should use a service with a Looper, a Timer and a Handler. Is that correct?
Could anybody point me to a tutorial which explains exactly what to do, step by step? Or at least suggest keywords I should look for?
All I found so far are snippets of code which don't work together when I try to assemble it. Possibly because I am not searching for the right terms?
Thanks, Dan
You could try the following approach:
Create a service that runs in the background to check for newly added data in the server.
If you prefer to make it user-driven, you can let users refresh the list on the device to actually trigger the requests to the server.
Libraries like Retrofit can make your life easier when it comes to making http requests - always avoid the main UI thread when doing this.
Another library that you could use to decouple your application using Events is EventBus. Assuming you are running a background service to check for updates, you can use EventBus to update your User Interfaces when something new is retrieved from the server through a GET request.
I hope this gives you an idea on how to proceed with the solution. Good luck!
I have a language translation app that needs to download some initial data on the first run. When the app is first launched, the first step is to get a list of currently supported languages from the server. The user then selects which they wish to install, and the rest of the tables are then downloaded.
I check if the languages are present in the local db, and if not, connect to the server and download them as JSON. The user cannot do anything until this data is retrieved from the server.
If there is no network connection, a dialog should prompt the user to go to their WIFI settings. If there is a network error with the download, another dialog would then prompt the user to retry now, or wait until later. If the download succeeds, a new Intent is launched to send them to choose the languages to install.
I have this mostly functioning (my AlertDialogs aren't showing), but the question is whether this is the proper way to accomplish this. I've currently set it up as an AsyncTask, but I've seen plenty of posts with responses yelling about how an AsyncTask should not be used when the UI depends on it. Fair enough, but an AsyncTask seems to be the recommended method for downloading data.
Is an AsyncTask the correct way to download the data, or is there a preferred alternative?
How to best deal with this on the UI, as it depends on this data? A splash screen? I'd rather not, but it seems something should be there, and I need somewhere to display the AlertDialogs if necessary.
Is an AsyncTask the correct way to download the data, or is there a preferred alternative?
No, AsyncTask is not a good solution for networking because:
You need a component from where you start this task. Activity is not a good choice because your network request will be tied to the UI and it will be hard to handle screen rotations, etc.
AsyncTask works on a global serial executor by default. It will block all other async tasks in the app until it finishes. So you will have to provide your own executor to avoid that.
The process level would be Background Process according to http://developer.android.com/guide/components/processes-and-threads.html
With a Service you can achieve Service Process which is better.
Use Service instead. You can implement any threading you want inside. You can use a regular Thread, a ThreadPoolExecutor, a Handler, or some third party solution. Service provides you great flexibility.
Regarding your second question, take a look at material design spec first: https://www.google.com/design/spec/material-design/introduction.html
Come up with some ideas and then ask a separate question if that is still not clear.
I'm using Fragments and LoaderManager. I have to launch an unknown number of tasks, and they might be run in parallel (otherwise I'd just reuse one and only one loader). For example, I have a listview, and each row might have a button to save the content of that row to a webserver. The user could initiate a save request on multiple items in parallel.
private int nextId = 0;
private void onClickListener() {
Bundle bundle = new Bundle();
bundle.putNextData(...);
getLoaderManager().initLoader(nextId++, bundle, this);
}
I could try bookkeeping myself, so create a pool of loaders manually and reuse them when possible, seems like it might be something already implemented by the API?
Thanks
I don't think you should use a Loader for saving data to a remote server.
Instead, use an IntentService or something similar to process a queue of "save" operations. This way, your communication with the web server can be batched, collapsed (i.e. multiple queued saves for a single item can be collapsed into one operation), and will live beyond the lifespan of your activity if need be.
A save queue processed by an IntentService (or equivalent) is also a great way to retry failed operations with backoff, since you can implement delayed retries with exponential backoff using AlarmManager.
An IntentService or bound service are always good approaches for that.
As Roman points, note that enqueuing several requests and called them separately is not highly recommended (it is very likely that you give a lot of work to the radio connection - when using data - which among other things drain your battery. Here is must-read about that)
I'd personally recommend to use a bound service with a queue of requests and a pool of threads available (that approach gives you full control for more complex network operations like in your case). There are more details on the approach here and a testcase working example over here.
Update us about your progress.
You are at the right direction, let me just help you a bit.
Reusing is indeed a good idea, and you do not have to worry about it because Android did it for you(Or Java actually ;)
It called ThreadPoolExecuter, you can start as many tasks as you wish and he will only open the predefined number of threads.(Best practice is trying to open as many threads as parallel network connection can be run on the device. From my research it is between 4 - 9).
And if you are trying to download same URL twice may be you can protect your self and open only one task for it.
I'm building this client for a web service.
Pretty much everything makes requests to a server and now what I do is, I open a new thread and put all my requests in the same thread. That means I'm making all my requests in a serial way inside the thread and that turns into a lot of waiting for the user. Aiming to make the application faster, I want to make every server request in an asynchronous way.
I have a Networking class that handles all the HTTP requests I need and I'm thinking of making it so that every request starts its own thread.
I'm thinking of using ASyncTask for this but I noticed that with ASyncTask I'd need a class for each of my http requests (a class for GET, POST, PUT, etc). Is that the best way of doing it? is there a more efficient/clean way of doing this? What do you guys suggest.
Seems like a design decision that will depend on exactly what you are up to. There are various ways in Android to execute tasks depending on whether the user is waiting for some data or is being notified later on once the background task completes.
I would suggest you to look at this post that compares various task mechanisms in Android. Apart from this also go through the java.util.concurrent package.
I'm sorry this is not a concrete answer, but take it from me - it mostly depends on how are you trying to serve the user. So one can only suggest ideas. Hope this helps.
I have an app that checks GPS position and interacts with four websites. I am thinking of using ASync tasks within a Service. The result from each website does not depend on any other website.
As finding the location and interacting with each website will take a different amount of time, does this mean I should have five services? Or should it all be combined into one service?
You need to call the other 4 services after you get a GPS fix. You can create new instances of each AsyncTask running in parallel. I don't see the need for using a service. I use one httpClient object stored in an application class for all web requests.
You don't need additional services. The problem here, as I understand, is that each HTTP call might take a long time to finish and that would slow down the whole process and that you will have too many ASynkTasks. Then, Google has already solved the problem for you.
Instead of using ASyncTasks you can use Volley and send all your requests to websites in parallel. That way, Volley will handle your requests in different threads and keep everything tidy. As a bonus it is A LOT faster than ASyncTask.