Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return anonymous List or ArrayList on AsyncTask in Android

I've 6 different type of List results after completing AsyncTask. And the List results are should be returned to an Activity. For example: List<A>, List<B>, List<C>, List<D>, List<E> and finally List<F>.

This is my AsyncTask:

public class myAsync extends AsyncTask<String, String, List> {

    private List resultList;

    @Override
    protected List doInBackground(String... params) {
        //params[0] is url
        //params[1] is type
        callAPI api = new callAPI(params[0], params[1]);
        // According to type api decides type of List and generates
        return api.getJSON(); // returns a List which already parse JSON
    }

    @Override
    protected void onPostExecute(List result) {
        // Result is here now, may be 6 different List type.
        this.resultList = result 
    }

    // returns result
    public List getResultList() { return this.resultList; }
}

I'll call AsyncTask like this:

myAsync task = new myAsync();
task.execute(params);
List myList = task.getResultList(); // type is uncertain
Log.d("Tag", Integer.toString(myList.size());

You know, I must point out the return type (Result) between <> tags. If I choose specific type for List, it does not work for other types.

Indeed, I already tried to return List<Object> and only List types. But doesn't worked.

I don't want to use 6 different Async. Is it possible to solve this with an only AsyncTask? I guess I need anonymous List or something similiar not sure. Can anyone explain this?

like image 273
Ogulcan Orhan Avatar asked Jan 26 '12 15:01

Ogulcan Orhan


2 Answers

First, I should point out that the sequence in which you're obtaining the list is not correct. Let me demonstrate:

// Initialize myAsync
myAsync task = new myAsync();

// This will do work for some period of time, this statement DOES NOT 'block'
// till myAsync completes, it will run it in the background
task.execute(params);

// This will return null because by the time you get here, task.execute most
// likely hasn't finished yet.
task.getResultList();

Edit: Now that you've included what you want to do with the list result, here's how you would modify your onPostExecute method:

@Override
protected void onPostExecute(List result) {
  Log.d(TAG, "The returned list contains " +result.size()+ "elements");
  // Do anything else you need to with the returned list here
}

So to summarize, if you needed to do anything else with the returned lists (besides printing their size), for example compare, print items, etc, you need to do that in the onPostExecute method.

like image 162
Marvin Pinto Avatar answered Nov 20 '22 18:11

Marvin Pinto


Depending on what the contents of the list is (What are A, B, C etc.), you might be able to make an interface for them.

So if A, B, C etc are objects, you can make an Interface that we call ListContentInterface. Each of your elements must then implement the ListContentInterface. You can then point out the type as:

List<ListContentInterface>.

After that you can then test what the contents of the list really is, by taking the first element of the list, and checking it's class:

if(element.getClass() == ClassToTestFor.class) ...

If the objects have any methods in common, you should specify them in the interface. If they have ALL methods in common, you can use the List list directly, without testing for the class of the objects (As they can all do what the interface defines).

I hope this makes some sense to you. It might not be the best use of interfaces or the best solution, but it might solve your problem.

like image 2
Rasmus Øvlesen Avatar answered Nov 20 '22 17:11

Rasmus Øvlesen