onBackPressed时Cancle AsyncTask

时间:2018-01-08 00:16:09

标签: java android android-asynctask

点击使用此代码后退AsyncTask时,我正在尝试 cancle 我的Button

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        if(playerTask!=null && !playerTask.isCancelled()) playerTask.cancel(true);
        this.finish();
    }

但是不起作用 playerTask 仍然有效:

  PlayerTask playerTask = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pop_for_ringtone);
        mediaPlayer = new MediaPlayer();
        playerTask = new PlayerTask();
        playerTask.execute(url);

/***/

 @SuppressLint("StaticFieldLeak")
    public class PlayerTask extends AsyncTask<String, Void, Boolean> {
        ProgressBar pb = findViewById(R.id.progress);

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                AudioAttributes attribs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
                mediaPlayer.setAudioAttributes(attribs);

            } else {
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            }
        }

        @Override
        protected Boolean doInBackground(String... strings) {
            if(!isCancelled()) {
            try {
                mediaPlayer.setDataSource(strings[0]);
                mediaPlayer.prepare();
                prepared = true;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.start();
                }
            });

        }
        else
        {
            playerTask.cancel(true);
        }
        return prepared;

        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            music.setEnabled(true);
            music.setVisibility(View.VISIBLE);
            music.setChecked(true);
        }
    }

4 个答案:

答案 0 :(得分:1)

你有2个问题需要改变。

1.在取消super.onBackPressed();之前致电playerTask时,您的活动将首先销毁。因此,您应在playerTask取消后致电。

2.当您判断playTask正在运行时,您还需要使用playerTask.getStatus() == AsyncTask.Status.RUNNING

更改

@Override
public void onBackPressed() {
    super.onBackPressed();
    if (mediaPlayer.isPlaying()) {
        mediaPlayer.stop();
    }
    if(playerTask!=null && !playerTask.isCancelled()) playerTask.cancel(true);
    this.finish();
}

@Override
public void onBackPressed() {
    if (mediaPlayer.isPlaying()) {
        mediaPlayer.stop();
    }
    if(playerTask!=null && !playerTask.isCancelled() && playerTask.getStatus() == AsyncTask.Status.RUNNING){
        playerTask.cancel(true);
        playerTask = null;
    }
    super.onBackPressed();
    this.finish();
}

答案 1 :(得分:1)

参考AsyncTask.cancel(boolean)AsyncTask cancel(boolean)的文档,我们发现此方法仅将isCancelled()设置为true并导致onCancelled()函数执行而不是onPostExecute()。因此,如果您需要正确取消AsyncTask,则需要添加一个标志以定期检查if(!isCancelled())中的doInBackground()并停止执行。您的代码看起来像这样

@Override
        protected Boolean doInBackground(String... strings) {

            if(!isCancelled()){
            //ToDo:whatever you need to do in the asynctask
            }
            else{
            //ToDo: cancel the execution
            }
            }

        }
  MediaPlayer mediaPlayer = new MediaPlayer();
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
    AudioAttributes attribs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
    mediaPlayer.setAudioAttributes(attribs);

  } else {
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  }
  mediaPlayer.setDataSource(url);
  mediaPlayer.prepareAsync();
  mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
      mediaPlayer.start();
      music.setEnabled(true);
      music.setVisibility(View.VISIBLE);
      music.setChecked(true);
    }
  });

然后onBackPressed()你可以mediaPlayer.release()

答案 2 :(得分:1)

试试这个

@Override
public void onBackPressed() {
    // if playerTask == null mediaPlayer is never start, no need to handle

    if(playerTask != null && playerTask.getStatus() == AsyncTask.Status.FINISHED) {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
    } else if (playerTask != null && playerTask.getStatus() != AsyncTask.Status.FINISHED) {
        // It mean your task is running, should stop your mediaPlayer inside your task
        playerTask.cancel(true);
    }
   super.onBackPressed();
}

并在您的PlayerTask覆盖onCancelled方法

@Override
protected void onCancelled(Boolean aBoolean) {
    if(isCancelled() && mediaPlayer.isPlaying()) {
         mediaPlayer.stop();
    }
}

希望有所帮助

答案 3 :(得分:1)

  

我在使用以下代码播放媒体时创建了wave,        并在点击后退按钮或停止按钮时停止播放器。

     

在xml文件中复制。

<VisualizerView
            android:id="@+id/waveform_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"/>
  

MainActivity.java

private MediaPlayer myMediaPlayer;      
private VisualizerView mWaveformView;   
Visualizer audioOutput = null;

onCreate()
{
     mWaveformView = (VisualizerView) findViewById(R.id.waveform_view);
     myButtonPlayLastRecordAudio.setOnClickListener(this);
}

  @Override
    public void onClick(View v) {
        switch (v.getId()) {
              case R.id.buttonPlay:
                myAudioSavePathInDevice = Environment.getExternalStorageDirectory().toString() + "/" +
                        "AudioRecording.3gp";


                myMediaPlayer = new MediaPlayer();
                myMediaPlayer.setVolume(1.5f, 1.5f);
                if (myAudioSavePathInDevice == null || myAudioSavePathInDevice.isEmpty()) {
                    Toast.makeText(MainActivity.this, "No Audio Found", Toast.LENGTH_LONG).show();
                } else {
                    try {
                        FileInputStream is = new FileInputStream(myAudioSavePathInDevice);
                        myMediaPlayer.setDataSource(is.getFD());


                        myMediaPlayer.prepare();
                        myMediaPlayer.start();
                        Toast.makeText(AudioRecordingActivity.this, "Recording Playing", Toast.LENGTH_LONG).show();

                        mWaveformView.clear();
                        createVisualizer();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    myMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            audioOutput.setEnabled(false);
                        }
                    });
                }

                break;

            case R.id.buttonStopAudio:
                mediaPlayerReleaseResources();

                break;

        }
}



 private void createVisualizer() {
        int rate = Visualizer.getMaxCaptureRate();
        audioOutput = new Visualizer(myMediaPlayer.getAudioSessionId()); // get output audio stream

        audioOutput.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
            @Override
            public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
                int max = 0, min = 255;
                for (int i = 0; i < waveform.length; i++) {
                    int w = (int) waveform[i] & 0xFF;
                    max = Math.max(w, max);
                    min = Math.min(w, min);
                }
                mWaveformView.addAmplitude((max - min)); // update the VisualizeView
                mWaveformView.invalidate(); // refresh the VisualizerView
            }

            @Override
            public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {

            }
        }, rate, true, false); // waveform not freq data
        audioOutput.setEnabled(true);
    }


     private void mediaPlayerReleaseResources() {
        if(myMediaPlayer != null) {
            if (myMediaPlayer.isPlaying()) {
                myMediaPlayer.stop();
            }
        }
        if( audioOutput != null)
            audioOutput.setEnabled(false);
    }


     @Override
    public void onBackPressed() {
        super.onBackPressed();
        mediaPlayerReleaseResources();
    }
  

VisualizerView.class

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class VisualizerView extends View {
    private static final int LINE_WIDTH = 3; // width of visualizer lines
    private static final int LINE_SCALE = 4; // scales visualizer lines
    private List<Float> amplitudes; // amplitudes for line lengths
    private int width; // width of this View
    private int height; // height of this View
    private Paint linePaint; // specifies line drawing characteristics

    private float temp_scale = 3;
    float heighest = temp_scale;

    // constructor
    public VisualizerView(Context context, AttributeSet attrs) {
        super(context, attrs); // call superclass constructor
        linePaint = new Paint(); // create Paint for lines
        linePaint.setColor(Color.BLACK); // set color to green
        linePaint.setStrokeWidth(LINE_WIDTH); // set stroke width
    }

    // called when the dimensions of the View change
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        width = w; // new width of this View
        height = h; // new height of this View
        amplitudes = new ArrayList<Float>(width / LINE_WIDTH);

    }

    // clear all amplitudes to prepare for a new visualization
    public void clear() {
        heighest = 3;
        amplitudes.clear();
    }

    // add the given amplitude to the amplitudes ArrayList
    public void addAmplitude(float amplitude) {
        amplitudes.add(amplitude); // add newest to the amplitudes ArrayList

        // if the power lines completely fill the VisualizerView
        if (amplitudes.size() * LINE_WIDTH >= width) {
            amplitudes.remove(0); // remove oldest power value
        }
    }

    // draw the visualizer with scaled lines representing the amplitudes
    @Override
    public void onDraw(Canvas canvas) {
        int middle = height / 2; // get the middle of the View
        float curX = 0; // start curX at zero

        // for each item in the amplitudes ArrayList
        for (float power : amplitudes) {
            heighest = Math.max(power, heighest);
            temp_scale = heighest / height;

            float scaledHeight = power / temp_scale; // LINE_SCALE; // scale the power
            curX += (LINE_WIDTH); // increase X by LINE_WIDTH
            // draw a line representing this item in the amplitudes ArrayList
            canvas.drawLine(curX, middle + scaledHeight / 2, curX, middle
                    - scaledHeight / 2, linePaint);
        }
    }

}