3

Update1

activity:

public Integer _number = 0;
@Override
    public void onCreate(Bundle savedInstanceState) {
if (_number >0)
        {
            Log.d("onSuccessfulExecute", ""+_number);
        }
        else
        {
            Log.d("onSuccessfulExecute", "nope empty songs lists");
        }
}

public int onSuccessfulExecute(int numberOfSongList) {

_number = numberOfSongList;

if (numberOfSongList >0)
{
    Log.d("onSuccessfulExecute", ""+numberOfSongList);
}
else
{
    Log.d("onSuccessfulExecute", "nope empty songs lists");
}
    return numberOfSongList;
}

end Update1

UPDATE: AsynchTask has its own external class.

How to pass an value from AsyncTask onPostExecute()... to activity

my code does returning value from onPostExecute() and updating on UI but i am looking for a way to set the activity variable (NumberOfSongList) coming from AsynchTask.

AsyncTask class:

@Override
    public void onPostExecute(asynctask.Payload payload)
    {  
         AsyncTemplateActivity app = (AsyncTemplateActivity) payload.data[0];

             //the below code DOES UPDATE the UI textView control
             int answer = ((Integer) payload.result).intValue();
             app.taskStatus.setText("Success: answer = "+answer);

            //PROBLEM:
            //i am trying to populate the value to an variable but does not seems like the way i am            doing:
            app.NumberOfSongList = payload.answer;
            ..............
            ..............
    }

Activity:

  public Integer NumberOfSongList;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 

        //Several UI Code   
        new ConnectingTask().execute();
        Log.d("onCreate", ""+NumberOfSongList);

    } 
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406
  • If you expect to see the `NumberOfSongsList` in that `Log.v()` call it will probably not happen because the `AsyncTask` didn't finish its job. What exactly is that `asynctask.PayLoad` response? – user Mar 16 '12 at 18:41
  • It certainly will not be updated at the Log.d("onCreate.... that you are showing. The overhead of asyncTask and threads will insure this. Did you check the value is updated later on in the program? – eyespyus Mar 16 '12 at 18:44
  • yes its not updating at the log.d i am aware of that.. that's why i need help... yes it does updating the value in onPostExecute and i can see it but not in the activity. – Nick Kahn Mar 16 '12 at 20:14

3 Answers3

2

What about using a setter method? e.g.

private int _number;
public int setNumber(int number) {
    _number = number;
}

UPDATE:

Please look at this code. This will do what you're trying to accomplish.

Activity class

public class TestActivity extends Activity {
    public int Number;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.test);

        Button btnDisplay = (Button) findViewById(R.id.btnDisplay);
        btnDisplay.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Toast toast = Toast.makeText(v.getContext(), "Generated number: " + String.valueOf(Number), Toast.LENGTH_LONG);
                toast.show();               
            }
        });

        new TestTask(this).execute();
    }
}

AsyncTask class

public class TestTask extends AsyncTask<Void, Void, Integer> {
    private final Context _context;
    private final String TAG = "TestTask";
    private final Random _rnd;

    public TestTask(Context context){
        _context = context;
        _rnd = new Random();
    }

    @Override
    protected void onPreExecute() {
        //TODO: Do task init.
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(Void... params) {
        //Simulate a long-running procedure.
        try {
            Thread.sleep(3000);         
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage());
        }

        return _rnd.nextInt();
    }

    @Override
    protected void onPostExecute(Integer result) {
        TestActivity test = (TestActivity) _context;
        test.Number = result;       
        super.onPostExecute(result);
    }
}
Serlite
  • 12,130
  • 5
  • 38
  • 49
Mauro
  • 58
  • 5
  • also this will not work because the AsyncTask did not finish the job as slukian pointed out and which make sense and i have noticed that while i was debugging. – Nick Kahn Mar 16 '12 at 20:17
  • thanks but i have a question, why do i need to hard-code the activity name `TestActivity test = (TestActivity) _context;` i am working on a class that any activity should be able to call but if i go with your approach i see that activity is hard-coded... any thoughts? – Nick Kahn Mar 17 '12 at 01:50
  • _context can be any Activity, I just used TestActivity for a quick demo of accessing my activity field. – Mauro Mar 17 '12 at 21:10
1

Just a word of caution: Be very careful when attempting to hold a reference to an Activity instance in an AsyncTask - I found this out the hard way :). If the user happens to rotate the device while your background task is still running, your activity will be destroyed and recreated thus invalidating the reference being to the Activity.

px3j
  • 236
  • 1
  • 2
  • as you can see and i have been struggling to work with having AsyncTask in its own class rather than a sub-class with activity but seems like its very challenging.... and i am started to realized does not make any diff, having its own class vs. having sub class .. any thoughts? – Nick Kahn Mar 16 '12 at 20:48
  • Can you let me know what type of function the AsyncTask is performing? (calling web service, etc.)? – px3j Mar 16 '12 at 21:34
  • I would suggest doing what the post below suggests, adding a setter method to your Activity then set a breakpoint in the debugger and see if the setter is getting called. But keep in mind that at some point you will have to handle the Activity being destroyed/recreated while the doInBackground() method is executing. I found this video very informative: [link](http://www.youtube.com/watch?v=xHXn3Kg2IQE) – px3j Mar 17 '12 at 00:28
0

Create a listener.

Make a new class file. Called it something like MyAsyncListener and make it look like this:

 public interface MyAsyncListener() {
      onSuccessfulExecute(int numberOfSongList);
 }

Make your activity implement MyAsyncListener, ie,

 public class myActivity extends Activity implements MyAsyncListener {

Add the listener to the constructor for your AsyncTask and set it to a global var in the Async class. Then call the listener's method in onPostExecute and pass the data.

 public class MyCustomAsync extends AsyncTask<Void,Void,Void> {

      MyAsyncListener mal;

      public MyCustomAsync(MyAsyncListener listener) {
           this.mal = listener;
      }

      @Override
      public void onPostExecute(asynctask.Payload payload) {
           \\update UI
           mal.onSuccessfulExecute(int numberOfSongList);
      }
 }

Now, whenever your AsyncTask is done, it will call the method onSuccessfulExecute in your Activity class which should look like:

 @Override
 public void onSuccessfulExecute(int numberOfSongList) {
      \\do whatever
 }

Good luck.

Zaid Daghestani
  • 8,555
  • 3
  • 34
  • 44