1

I have a lot of buttons on main activity. Each button run this same AsyncTask which do HTTP POST method but post different values (which I store in Button.Tag property). So I have one AsyncTask for all buttons. Problem is when AsyncTask done his job, it should know which button must be updated in callback (button which execute AsyncTask). I don't want pass object (button instance) to AsyncTask because I read that activity can be recreated by system in many situations (orientation change, etc), so object passed to AsyncTask could be invalid. But what about View.ID property? It can be changed by system in activity life cycle too or can I use this integer value, pass it to AsyncTask and in onPostExecute find this button by this ID (calling findViewByID)?

Regards

Dalmas
  • 26,409
  • 9
  • 67
  • 80
Dibo
  • 1,159
  • 17
  • 34

5 Answers5

2

The id of an element can not be changed because it is generated by Android on the R.java. So you can use this value I think.

Stephane Mathis
  • 6,542
  • 6
  • 43
  • 69
1

You should have an observer within your AsyncTask that you can null when your Activity disappears.

Example

Activity:

private List<MyAsyncTask> mMyAsyncTasks;

private void addAsyncTask(MyAsyncTask task) {
    mMyAsyncTasks.add(task);
}

public void onDestroy() {
    for(MyAsyncTask task : mMyAsyncTasks) {
        task.removeObserver();
    }
}

Async Tasks:

public class MyAsyncTask extends AsyncTask<Something, Something, Something> {
    private MyAsyncTaskObserver mObserver;
    private int mButtonId;

    public MyAsyncTask(MyAsyncTaskObserver observer, int buttonId) {
        mObserver = observer;
        mButtonId = buttonId;
    }

    public void removeObserver() {
        mObserver = null;
    }

    public void onPostExecute(Something result) {
        ...
        if (mObserver != null) {
            mObserver.onMyDataAvailable(result, mButtonId);
        }
    }
}

Also, your AsyncTask should not be inside your Activity, as it can result in a memory leak if your Activity is destroyed.

WindyB
  • 786
  • 3
  • 9
1

A simple idea would be to pass a unique value that identifies a particular button.For instance if button1 is clicked pass 'button1' to the async task.In post execute we can use switch cases to update the desired button.As simple as that.

Edit:Better still use the findViewWithTag method to identify the button,since you are already sending a tag value to the asynctask.No need to use switch cases in this case

Mukund Samant
  • 1,079
  • 7
  • 12
0

Yes, if you ensure your views all have unique identifiers, whether made in XML or code - and then call findViewById(int id) on your ViewGroup to get the correct view after your AsyncTask has finished (override onPostExecute() in AsyncTask to ensure you're on the UI thread).

EDIT: This is assuming you have created your AsyncTask in a fragment/activity and can call getView() on it to get your hierarchy.

0

If you have your async task inside you activity as inner class you can use the integer id value in OnPostExecute by calling findViewById(int id).

In other cases you to pass viewGroup which is holding your buttons.

Orest
  • 1,857
  • 5
  • 19
  • 27
  • This can result in a memory leak if the Activity is destroyed while the AsyncTask is in doInBackground. He would have to destroy the AsyncTask in the onDestroy method of his Activity. – WindyB Jun 26 '12 at 14:11
  • I know that this answer has now been marked as accepted, but once again, I stress that this causes a memory leak, and can lead to unexpected functionality in the future. See http://stackoverflow.com/questions/3033007/android-memory-leak-due-to-asynctask – WindyB Jun 26 '12 at 22:32
  • If async task is inner class of activity everything will be OK. Leak can be caused only in case of passing viewGroup. – Orest Jun 28 '12 at 12:16
  • That's not true. Inner classes hold an implicit reference to their containing class, which is why findViewById would work from inside the AsyncTask. See http://c2.com/cgi/wiki?InnerClass – WindyB Jul 03 '12 at 14:30