Ideal way to cancel an executing AsyncTask

前端 未结 9 2110
不思量自难忘°
不思量自难忘° 2020-11-22 05:54

I am running remote audio-file-fetching and audio file playback operations in a background thread using AsyncTask. A Cancellable progress bar is sh

相关标签:
9条回答
  • 2020-11-22 06:47

    This is how I write my AsyncTask
    the key point is add Thread.sleep(1);

    @Override   protected Integer doInBackground(String... params) {
    
            Log.d(TAG, PRE + "url:" + params[0]);
            Log.d(TAG, PRE + "file name:" + params[1]);
            downloadPath = params[1];
    
            int returnCode = SUCCESS;
            FileOutputStream fos = null;
            try {
                URL url = new URL(params[0]);
                File file = new File(params[1]);
                fos = new FileOutputStream(file);
    
                long startTime = System.currentTimeMillis();
                URLConnection ucon = url.openConnection();
                InputStream is = ucon.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
    
                byte[] data = new byte[10240]; 
                int nFinishSize = 0;
                while( bis.read(data, 0, 10240) != -1){
                    fos.write(data, 0, 10240);
                    nFinishSize += 10240;
                    **Thread.sleep( 1 ); // this make cancel method work**
                    this.publishProgress(nFinishSize);
                }              
                data = null;    
                Log.d(TAG, "download ready in"
                      + ((System.currentTimeMillis() - startTime) / 1000)
                      + " sec");
    
            } catch (IOException e) {
                    Log.d(TAG, PRE + "Error: " + e);
                    returnCode = FAIL;
            } catch (Exception e){
                     e.printStackTrace();           
            } finally{
                try {
                    if(fos != null)
                        fos.close();
                } catch (IOException e) {
                    Log.d(TAG, PRE + "Error: " + e);
                    e.printStackTrace();
                }
            }
    
            return returnCode;
        }
    
    0 讨论(0)
  • 2020-11-22 06:54

    Simple: don't use an AsyncTask. AsyncTask is designed for short operations that end quickly (tens of seconds) and therefore do not need to be canceled. "Audio file playback" does not qualify. You don't even need a background thread for ordinary audio file playback.

    0 讨论(0)
  • 2020-11-22 06:59

    The thing is that AsyncTask.cancel() call only calls the onCancel function in your task. This is where you want to handle the cancel request.

    Here is a small task I use to trigger an update method

    private class UpdateTask extends AsyncTask<Void, Void, Void> {
    
            private boolean running = true;
    
            @Override
            protected void onCancelled() {
                running = false;
            }
    
            @Override
            protected void onProgressUpdate(Void... values) {
                super.onProgressUpdate(values);
                onUpdate();
            }
    
            @Override
            protected Void doInBackground(Void... params) {
                 while(running) {
                     publishProgress();
                 }
                 return null;
            }
         }
    
    0 讨论(0)
提交回复
热议问题