当我点击使用此代码后退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);
}
}
答案 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);
}
}
}