JLTChiu
JLTChiu

Reputation: 1023

How to preserve data generated in an AsyncTask?

I am working on Android AsyncTask, I wish to make a progress bar during my program is loading. Here's how I make it.

A class is declared here...
private ArrayList<String> result1 = new ArrayList<String>(); //class variable

onCreate()
{
    Some stuff here...
    new ATask().execute();
     for (int i = 0; i <result1.size();i++)
    {
        output = output +result1.get(i) + "\n\n";
    }
    textView.setText(output);
}
private void do0()
{
    ArrayList<Sentence> result = new ArrayList<Sentence>();
    ArrayList<String> result2 = new ArrayList<String>();
    result = do1("link", true); //just some function I am working
    result1 = do2(result,10);//do2 return ArrayList<String>
}
private class ATask extends AsyncTask<String, Void, String>{
    private ProgressDialog progress = null;
    @Override
    protected String doInBackground(String... params) {
        do0();
        return null;
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    @Override
    protected void onPostExecute(String result) {
        progress.dismiss();

        //adapter.notifyDataSetChanged();

        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        progress = new ProgressDialog(ReadWebPage.this);

        progress.setMessage("Doing...");
        progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progress.show();

        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }
};

My intention is that, while the progress bar is loading, it will finish the do0() and modify result1, then my oncreate can use that result1 to display in it's TextView. However my TextView is always empty in this setting. So I move the

     for (int i = 0; i <result1.size();i++)
    {
        output = output +result1.get(i) + "\n\n";
    }
    textView.setText(output);

into the do0() (right after the result1 = do2()), but then the program will crash. I am not familiar with these thread settings, thanks for your help in advance.

Upvotes: 0

Views: 120

Answers (2)

Seva Alekseyev
Seva Alekseyev

Reputation: 61378

You'll be better served with a thread that holds a Handler object that was initialized on the main thread. Using the handler, you can post() little snippets to be executed on a main thread - like update a progress bar. You can do the same Handler trick from the AsyncTask, but IMHO threads are cleaner.

Said snippets should be implemented as Runnables. Feel free to use a nested anonymous class one-liner.

Upvotes: 2

Eric Levine
Eric Levine

Reputation: 13564

The problem is with the design of your code. AsyncTask happens asynchronously, so as soon as you call execute on your AsyncTask the rest of your onCreate will execute immediately. AsyncTask will essentially run on a new thread and execute in parallel with your Activity.

What I think you want is to set your TextView in the onPostExecute method of your AsyncTask. onPostExecute gets called after doInBackground is finished.

Also, it is important to keep in mind that doInBackground happens on a background thread, so you cannot make changes to your Activity's UI from code within it. onPre/PostExecute run on the UI thread, so you can make UI changes there, but any code within those methods will also block the UI.

Upvotes: 2

Related Questions