3

I am a relatively new Android developer and am working on an application right now that makes a lot of calls to a RESTful web service.

I am making each call in an asyncTask but in some files, the amount of different async tasks I have approaches 15. Right now I have them all as private classes inside my activity class. How can I organize them better(i.e. put them in separate files) while still being able to update the UI.. I was thinking of passing the context into the constructor of each asyncTask but I was just wondering if there was a best practice/better way.

Thanks!

mmBs
  • 8,421
  • 6
  • 38
  • 46
Marty Griffin
  • 349
  • 1
  • 5
  • 18
  • 2
    You should use a library like Volley instead of multiple asynctasks for your network requests. – tbruyelle Aug 21 '13 at 16:05
  • I agree with the mate above, or if you want to stick with AsyncTasks use a ThreadPool executor! – Pavlos Aug 21 '13 at 16:09
  • AsyncTasks can be executed in a [thread pool executor](http://developer.android.com/reference/android/os/AsyncTask.html#THREAD_POOL_EXECUTOR). Since it is public you could (ab)use it for other things as well. – zapl Aug 21 '13 at 17:03

3 Answers3

1

Passing in the Activity as a constructor parameter sounds like a good plan to me. Basically the same is happening when you declare them as an inner class.

But keep in mind, that there are some drawbacks for using AsyncTasks to load data. Once started, they will continue to run even when the activity is already closed and hold a reference to your activity (it can therefore not be garbage collected).

You may want to look into other concepts like loaders.

Henry
  • 42,982
  • 7
  • 68
  • 84
1

Instead of using so many classes for different types of asynctask , I suggest you use this library

you can have a look at here

http://loopj.com/android-async-http/

your code will become very very less , instead of declaring so may asynctask seperately writing bulk of code , you can just use 4 lines of code

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
    @Override
    public void onSuccess(String response) {
        System.out.println(response);
       }
});

I is very efficient in geting the response very quickly.

I hope this will help you out. :)

Udit Kapahi
  • 2,277
  • 1
  • 27
  • 25
1

Consider using a library to simplify your code base. I wrote droidQuery which, among other things, can be used to simplify AsyncTasks. For example, to get JSON data from example.com, and to have access to context afterwards, you can do this:

$.ajax(new AjaxOptions().url("http://www.example.com")
                        .context(this)
                        .type("GET")
                        .dataType("json")
                        .success(new Function() {
                            @Override
                            public void invoke($ droidQuery, Object... params) {
                                JSONObject json = (JSONObject) params[0];
                                Context context = droidQuery.context();
                                //TODO:
                            }
                        })
                        .error(new Function() {
                            @Override
                            public void invoke($ droidQuery, Object... params) {
                                AjaxError error = (AjaxError) params[0];
                                Log.e("Ajax", "Error " + error.status + ": " + error.reason);
                            }
                        }));

For lots of different requests that you call a lot, you can also create instances of AjaxOptions for later use, which have different URLs, types, dataTypes, etc:

Map<String, AjaxOptions> requests = new HashMap<String, AjaxOptions>();
//add the example above:
requests.put("example", new AjaxOptions().url("http://www.example.com")
                                         .context(this)
                                         .type("GET")
                                         .dataType("json")
                                         .success(new Function() {
                                             @Override
                                             public void invoke($ droidQuery, Object... params) {
                                                 JSONObject json = (JSONObject) params[0];
                                                 Context context = droidQuery.context();
                                                 //TODO:
                                             }
                                         })
                                         .error(new Function() {
                                             @Override
                                             public void invoke($ droidQuery, Object... params) {
                                                 AjaxError error = (AjaxError) params[0];
                                                 Log.e("Ajax", "Error " + error.status + ": " + error.reason);
                                             }
                                         }));

Then later, just perform this task by calling:

$.ajax(requests.get("example"));
Phil
  • 35,852
  • 23
  • 123
  • 164
  • `.context(this)` should probably be the application context. Storing references to activity context is bad unless it's only used during the activity lifetime. Async things tend to keep references way after that. – zapl Aug 21 '13 at 17:05
  • 2
    @zapl, this context object is also not necessary, but more of a convenience. Without it, the `droidQuery` param will be null. – Phil Aug 21 '13 at 17:17