0

(this is Not about nullpointer): I have a progress bar in AsyncTask and i added a cancel button to cancel asynctask.

i can cancel the asynctask from outside the asynctask but i need to implement cancel function in progressdialog which is implemented under asynctask.

So the question is how to cancel asynctask with cancel button which is implemented in progressdialog under asynctask?

plse do check in "doInBackground"..the asynctask is not getting cancel

Download_result.java class:

public class Download_result extends AsyncTask<String,Integer,Void>{
ProgressDialog progressDialog;
Context context;
String pdfFile;


Download_result(Context context, String pdfFile){
    this.context=context;
    this.pdfFile=pdfFile;
}
@Override
protected void onPreExecute() {
        progressDialog = new ProgressDialog(context);
        progressDialog.setTitle("Downloading...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMax(200);
        progressDialog.setCancelable(false);
        progressDialog.setProgress(0);
        progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Download_result.this.cancel(true);  
                dialog.dismiss();
            }
        });
        progressDialog.show();
}

@Override
protected Void doInBackground(String... params) {
      //given below
}
@Override
protected void onProgressUpdate(Integer... values) {
        progressDialog.setProgress(values[0]);       
}

@Override
protected void onPostExecute(Void result) {
        progressDialog.cancel();        

}
}

enter image description here

my "doInBackground" method:

@Override
    protected Void doInBackground(String... params) {      

            String url_1=params[0];
            int file_length=0;
            try {
                URL url = new URL(url_1);
                URLConnection urlConnection = url.openConnection();
                urlConnection.connect();
                file_length=urlConnection.getContentLength();
                filesize=file_length;
                File sdCard = Environment.getExternalStorageDirectory();
                File new_folder = new File (sdCard.getAbsolutePath() + "/xxx");


                File input_file = new File(new_folder,pdfFile);
                InputStream inputStream = new BufferedInputStream(url.openStream(),8192);
                byte[] data=new byte[1024];
                int total=0,count=0;
                OutputStream outputStream = new FileOutputStream(input_file);
                while ((count=inputStream.read(data))!=-1){
                    total+=count;
                    outputStream.write(data,0,count);


                    int progress= (total*200)/file_length;
                    downloadedsize=total;

                    publishProgress(progress);
                    if(isCancelled()){
                        break;  or return null; // same result
                    }


                }
                inputStream.close();
                outputStream.close();


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }           
        return null;//"Download completed!";
    }
wangz
  • 61
  • 1
  • 10

4 Answers4

2

you have not dismissed the dialog in cancel button press.. also use setButton instead

try this:

 @Override
protected void onPreExecute() {
        progressDialog = new ProgressDialog(context);
        progressDialog.setTitle("Downloading...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMax(200);
        progressDialog.setCancelable(false);
        progressDialog.setProgress(0);
        progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          download.cancel(true);
           downloadstatus=false;  //add boolean check
          dialog.dismiss();
        }
      });
        progressDialog.show();
}

To cancel an Async Task use:

 Public Download_result download;
 download = new Download_result();
 download.execute();
download.cancel(true);

try this in doInbackGround()

 while ((count=inputStream.read(data))!=-1){

                if(!your_AsyncTask.isCancelled() ||  downloadstatus !=false){
                    total+=count;
                    outputStream.write(data,0,count);
                    int progress= (total*200)/file_length;
                    downloadedsize=total;

                    publishProgress(progress);
                }else{
                    break;
                }
            }
rafsanahmad007
  • 23,683
  • 6
  • 47
  • 62
  • same result...actualy i was using setButton too..see my edited post, check where i am getting nullpointer – wangz Feb 12 '17 at 08:51
  • @wangz what is your `Download_result.java:62` line? – rafsanahmad007 Feb 12 '17 at 09:31
  • Download_result.java is a class where i implementing the above code(asynctask), and "download.cancel(true)" is in 62line... – wangz Feb 12 '17 at 09:37
  • to properly cancel the async task you have to use..`myTask.cancel(true);` as your `download` is null it causes the exception.. – rafsanahmad007 Feb 12 '17 at 10:31
  • thanx, though i have implemented what Code-Apprentice suggested but still the logic is same and now i am not getting any null pointer exception. but any way the asynctask is not getting cancel i am getting the downloaded file in file manager. i want it to be cancel in halfway. i might have made some mistake in my "doInBackground" plse check for me..plse plse – wangz Feb 12 '17 at 10:32
  • both myTask.cancel(true) and download.cancel(true) are same, you are declaring asynctask as myTask but i am declaring as download..only variable is different but reference is same. – wangz Feb 12 '17 at 10:56
  • that's y i said i have corrected it (now i am not getting null pointer exeption). Now i am not passing asynctask(download) as parameter. plse see ma edited post. – wangz Feb 12 '17 at 11:08
  • tanx you are awesome! – wangz Feb 12 '17 at 12:32
1
Download_result(Context context, String pdfFile,Download_result download)

It does not make any sense to send a Download_result as a parameter to its own constructor. You can never have a valid reference to pass the constructor. You should change this constructor to

Download_result(Context context, String pdfFile)

Every method of Download_result already has a reference to a Download_result object called this. Since you need access to it in an inner class, use Download_result.this:

progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        Download_result.this.cancel(true);
        dialog.dismiss();
    }
});
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • thank you, now i am not getting nullpointer exception. But still asynctask doesn't get cancel. i get downloaded file in file manager. I may have made some mistake in "doInBackground"..plse check for me. – wangz Feb 12 '17 at 10:26
  • @wangz That is because you only check `isCancelled()` once just as `doInBackground()` begins. You need to check this value periodically in order to detect if the AsyncTask is cancelled. – Code-Apprentice Feb 12 '17 at 10:38
  • @wangz You should post a new question since your original one was already answered. Feel free to link to this question in order to provide context. – Code-Apprentice Feb 12 '17 at 10:51
  • the main question was to cancel asynctask which is still not solved. :( – wangz Feb 12 '17 at 10:59
  • @wangz The original question was about an NPE. This **has** been solved. Please post a new question for further help. Comments and edits are for clarification, not to completely change the question. – Code-Apprentice Feb 12 '17 at 11:00
  • k i am posting, do reply to my post – wangz Feb 12 '17 at 11:09
0

Create a "boolean keepGoing" in your AsyncTask and set it to true. Within your "doInBackground" procedure poll it regularly and return, if false. Bind the cancel button to a setter within the AsyncTask which sets the "keepGoing" flag to false. That should do the job.

Martin G
  • 229
  • 1
  • 6
0

Use DialogInterface listener on ProgressDialog's button, e.g.:

protected void onPreExecute() {
            pd = new ProgressDialog(MainActivity.this);
            pd.setTitle("PAUL app");
            pd.setMessage("Loading data ...");
            pd.setButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // User has cancelled task ... just quit!
                    MainActivity.this.finish();
                    return;
                }
            });
            pd.show();
        }
nkmuturi
  • 248
  • 3
  • 10