ProgressDialog in AsyncTask

131,674

Solution 1

Fixed by moving the view modifiers to onPostExecute so the fixed code is :

public class Soirees extends ListActivity {
    private List<Message> messages;
    private TextView tvSorties;

    //private MyProgressDialog dialog;
    @Override
    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        setContentView(R.layout.sorties);

        tvSorties=(TextView)findViewById(R.id.TVTitle);
        tvSorties.setText("Programme des soirées");

        new ProgressTask(Soirees.this).execute();


   }


    private class ProgressTask extends AsyncTask<String, Void, Boolean> {
        private ProgressDialog dialog;
        List<Message> titles;
        private ListActivity activity;
        //private List<Message> messages;
        public ProgressTask(ListActivity activity) {
            this.activity = activity;
            context = activity;
            dialog = new ProgressDialog(context);
        }



        /** progress dialog to show user that the backup is processing. */

        /** application context. */
        private Context context;

        protected void onPreExecute() {
            this.dialog.setMessage("Progress start");
            this.dialog.show();
        }

            @Override
        protected void onPostExecute(final Boolean success) {
                List<Message> titles = new ArrayList<Message>(messages.size());
                for (Message msg : messages){
                    titles.add(msg);
                }
                MessageListAdapter adapter = new MessageListAdapter(activity, titles);
                activity.setListAdapter(adapter);
                adapter.notifyDataSetChanged();

                if (dialog.isShowing()) {
                dialog.dismiss();
            }

            if (success) {
                Toast.makeText(context, "OK", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "Error", Toast.LENGTH_LONG).show();
            }
        }

        protected Boolean doInBackground(final String... args) {
            try{    
                BaseFeedParser parser = new BaseFeedParser();
                messages = parser.parse();


                return true;
             } catch (Exception e){
                Log.e("tag", "error", e);
                return false;
             }
          }


    }

}

@Vladimir, thx your code was very helpful.

Solution 2

/**
 * this class performs all the work, shows dialog before the work and dismiss it after
 */
public class ProgressTask extends AsyncTask<String, Void, Boolean> {

    public ProgressTask(ListActivity activity) {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
    }

    /** progress dialog to show user that the backup is processing. */
    private ProgressDialog dialog;
    /** application context. */
    private ListActivity activity;

    protected void onPreExecute() {
        this.dialog.setMessage("Progress start");
        this.dialog.show();
    }

        @Override
    protected void onPostExecute(final Boolean success) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }


        MessageListAdapter adapter = new MessageListAdapter(activity, titles);
        setListAdapter(adapter);
        adapter.notifyDataSetChanged();


        if (success) {
            Toast.makeText(context, "OK", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(context, "Error", Toast.LENGTH_LONG).show();
        }
    }

    protected Boolean doInBackground(final String... args) {
       try{    
          BaseFeedParser parser = new BaseFeedParser();
          messages = parser.parse();
          List<Message> titles = new ArrayList<Message>(messages.size());
          for (Message msg : messages){
              titles.add(msg);
          }
          activity.setMessages(titles);
          return true;
       } catch (Exception e)
          Log.e("tag", "error", e);
          return false;
       }
    }
}

public class Soirees extends ListActivity {
    private List<Message> messages;
    private TextView tvSorties;
    private MyProgressDialog dialog;
    @Override
    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        setContentView(R.layout.sorties);

        tvSorties=(TextView)findViewById(R.id.TVTitle);
        tvSorties.setText("Programme des soirées");

        // just call here the task
        AsyncTask task = new ProgressTask(this).execute();
   }

   public void setMessages(List<Message> msgs) {
      messages = msgs;
   }

}

Solution 3

AsyncTask is very helpful!

class QueryBibleDetail extends AsyncTask<Integer, Integer, String>{
        private Activity activity;
        private ProgressDialog dialog;
        private Context context;

        public QueryBibleDetail(Activity activity){
            this.activity = activity;
            this.context = activity;
            this.dialog = new ProgressDialog(activity);
            this.dialog.setTitle("查询经文");
            this.dialog.setMessage("正在查询:"+tome+chapterID+":"+sectionFromID+"-"+sectionToID);
            if(!this.dialog.isShowing()){
                this.dialog.show();
            }
        }

        @Override
        protected String doInBackground(Integer... params) {
            Log.d(TAG,"经文doInBackground");
            publishProgress(params[0]);

            if(sectionFromID > sectionToID){
                return "";
            }

            String queryBible = "action=query_bible&article="+chapterID+"&id="+tomeID+"&verse_start="+sectionFromID+"&verse_stop="+sectionToID+"";
            try{
                String bible = (Json.getRequest(HOST+queryBible)).trim();
                bible = android.text.Html.fromHtml(bible).toString();
                return bible;
            }catch(Exception e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String bible){
            Log.d(TAG,"经文onPostExecute");
            TextView bibleBox = (TextView) findViewById(R.id.bibleBox);
            bibleBox.setText(bible);
            this.dialog.dismiss();
        }
    }

Solution 4

Don't know what parameter should I use?

A lot of Developers including have hard time at the beginning writing an AsyncTask because of the ambiguity of the parameters. The big reason is we try to memorize the parameters used in the AsyncTask. The key is Don't memorize. If you can visualize what your task really needs to do then writing the AsyncTask with the correct signature would be a piece of cake.

What is an AsyncTask?

AsyncTask are background task which run in the background thread. It takes an Input, performs Progress and gives Output.

ie AsyncTask<Input,Progress,Output>

Just figure out what your Input, Progress and Output are and you will be good to go.

For example

enter image description here

How does doInbackground() changes with AsyncTask parameters?

enter image description here

How doInBackground() and onPostExecute(),onProgressUpdate() are related?

enter image description here

How can You write this in a code?

 DownloadTask extends AsyncTask<String,Integer,String>{

    @Override
    public void onPreExecute(){
    }

    @Override
    public String doInbackGround(String... params)
    {
         // Download code
         int downloadPerc = // calculate that
         publish(downloadPerc);

         return "Download Success";
    }

    @Override
    public void onPostExecute(String result)
    {
         super.onPostExecute(result);
    }

    @Override
    public void onProgressUpdate(Integer... params)
    {
         // show in spinner, access UI elements
    }

}

How will you run this Task in Your Activity?

new DownLoadTask().execute("Paradise.mp3");

Solution 5

A couple of days ago I found a very nice solution of this problem. Read about it here. In two words Mike created a AsyncTaskManager that mediates ProgressDialog and AsyncTask. It's very easy to use this solution. You just need to include in your project several interfaces and several classes and in your activity write some simple code and nest your new AsyncTask from BaseTask. I also advice you to read comments because there are some useful tips.

Share:
131,674
Houssem
Author by

Houssem

Updated on July 08, 2022

Comments

  • Houssem
    Houssem almost 2 years

    I'm trying to display a custom progressdialog while loading RSS feed from an HTTP server, I made a hard search, but nothing helped me to do this, the only thing I know is that the solution should use AsyncTask, but I'm confusing about the params to pass to this AsyncTask. Here's my activity :

    public class Soirees extends ListActivity {
    
        private List<Message> messages;
        private TextView tvSorties;
        private MyProgressDialog dialog;
    
        @Override
        public void onCreate(Bundle icicle) {
    
            super.onCreate(icicle);
            setContentView(R.layout.sorties);
    
            tvSorties=(TextView)findViewById(R.id.TVTitle);
            tvSorties.setText("Programme des soirées");
    
            loadFeed();
    
        }
    
        private void loadFeed(){
    
            try{
                BaseFeedParser parser = new BaseFeedParser();
                messages = parser.parse();
                List<Message> titles = new ArrayList<Message>(messages.size());
                for (Message msg : messages){
                    titles.add(msg);
                }
                MessageListAdapter adapter = new MessageListAdapter(this,titles);
                this.setListAdapter(adapter);
                adapter.notifyDataSetChanged();
    
            } catch (Throwable t){
                Log.e("ImageLoader",t.getMessage(),t);
            }
        }
    
    }
    

    Can you please help me add AsyncTask to this?

  • Houssem
    Houssem over 13 years
    Thank you guys, so i'm trying this, and as i asked, which params shou i pass here ? protected Boolean doInBackground(final String... args) because the line MessageListAdapter adapter = new MessageListAdapter(this,titles) throws error
  • Vladimir Ivanov
    Vladimir Ivanov over 13 years
    activity will be enough. you just need to set list adapter.
  • Houssem
    Houssem over 13 years
    sorry Vlad, i'm totally confused :S (beginner case)
  • Houssem
    Houssem over 13 years
    Error : Only the original thread that created view hierarchy can touch its views.
  • Noby
    Noby over 12 years
    Can't create handler inside thread that has not called Looper.prepare() I am getting this error. how to resolve this.
  • Noby
    Noby over 12 years
    Can't create handler inside thread that has not called Looper.prepare() I am getting this error how to resolve this.
  • tasomaniac
    tasomaniac almost 12 years
    I think you need to add one more thing to this. You need to create a global private object to your AsyncTask and when the activity is destroyed you need to cancel the AsyncTask. In your case, if the user presses the back button before the AsyncTask is completed, the app will crash most probably.
  • Moises Jimenez
    Moises Jimenez over 11 years
    I've been trying to use a similar implementation but keep getting error over the fact the asynctask is not an activity and therefore I cannot display a dialog. Am I missing anything?
  • Mehdi
    Mehdi almost 8 years
    Your example is not answering the question, where did you get the context variable ?
  • Prakash
    Prakash about 7 years
    Don't create any UI elements like the progressDialog inside the asynctask. This might create problems with config changes or if something breaks inside doInBackground method onPostexecute will not be called in that case your dialog is never dismissed. There are better and cleaner ways of doing this. This article explains it androidresearch.wordpress.com/2013/05/10/…
  • Prakash
    Prakash over 6 years
    @Who ever down voted this. Could you please tell me what's wrong with this answer. That is one of the good article I read and would like to share with intermediate developers out there.
  • Vahe Gharibyan
    Vahe Gharibyan almost 6 years
    This solution is not much clean, because Context obj may cause of memory leak inside of AsyncTask. Use WeakReference<Context> for better performance.
  • Mehmet Katircioglu
    Mehmet Katircioglu almost 6 years
    Lock the screen orientation in order to prevent asynctask from being destroyed or for any other means is such a bad idea. Thats why I guess.
  • waghydjemy
    waghydjemy over 4 years
    Nice explanation
  • Ümañg ßürmån
    Ümañg ßürmån almost 4 years
    It would have been more better if you could have given a simple example code with it.