Ich habe eine AsyncTask, die Audio aufzeichnet. Das Problem ist, wenn ich cancel(true)
aus dem UI-Thread aufrufen, isCancelled()
kehrt true
(wie es angenommen hat, zu), aber die doInBackground
Funktion läuft weiter, und wenn ich getStatus()
auf dem AsyncTask laufen kehrt sie RUNNING und keiner der onCancelled
Methoden aufgerufen werden nore tut onPostExecute
...AsyncTask isCancelled() gibt true zurück aber doInBackground endet nicht
Da alle doInBackground
Code in while(!isCancelled())
platziert ist, sollte das Verfahren beendet, sobald die Aufgabe ...
die while (! isCancelled()) Schleife endet, sobald ich AsyncTask.cancel nennen(). Ich denke, das Problem ist, dass return null
nicht genannt zu werden, und deshalb doInBackground
nicht zu Ende ... ich aber falsch sein kann ...
Code:
package Classes;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.util.Log;
import com.appetizers.app.trytabs.Main2Activity;
/**
* Created by Alon on 09-Aug-16.
*/
public class RecordingTask2 extends AsyncTask<Void,Void,Void> {
AudioRecord record;
Context context;
int bufferSize;
int numSample=0;
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
short[] audioBuffer;
public RecordingTask2(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("RECTASK", "onPre");
record = findAudioRecord();
record.startRecording();
}
@Override
protected Void doInBackground(Void... params) {
audioBuffer = new short[bufferSize/2];
Log.d("RECTASK","before while");
while(!isCancelled())
{
//Log.d("RECTASK","isCancelled = "+isCancelled());
int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length);
numSample +=numberOfShort;
}
Log.d("RECTASK", "after while\nisCancelled = "+isCancelled());
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.d("RECTASK", "reached onCancel()");
end();
}
@Override
protected void onCancelled(Void aVoid) {
super.onCancelled(aVoid);
Log.d("RECTASK", "reached onCancelled(Void)");
end();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.d("RECTASK", "reached onPost");
end();
}
private void end()
{
Log.d("RECTASK","reached end function");
record.stop();
record.release();
((Main2Activity)context).setNumOfSamples(numSample);
((Main2Activity)context).setSamples(audioBuffer);
}
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
try {
Log.d("FINDAUDIO", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
Log.d("FINDAUDIO", "AudioRecorder state = "+recorder.getState());
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
return recorder;
}
} catch (Exception e) {
Log.e("FINDAUDIO", rate + "Exception, keep trying.",e);
}
}
}
}
return null;
}
}
Hier ist die Teil des Codes in meiner MainActivity Klasse, wo ich anrufen und brechen Sie die AsyncTask
recordSlideBar.setDownRun(new Runnable() {
@Override
public void run() {
Log.d("MAINACT","onDown");
if(recTask==null || recTask.getStatus()!= AsyncTask.Status.RUNNING) {
recTask = new RecordingTask2(Main2Activity.this);
recTask.execute();
}
}
});
recordSlideBar.setUpRun(new Runnable() {
@Override
public void run() {
Log.d("MAINACT", "onUp");
recTask.cancel(true);
Log.d("MAINACT", "after cancel\nstatus = "+recTask.getStatus());
while(recTask.getStatus()!= AsyncTask.Status.FINISHED)
{
//waiting for task to end...
}
ShortBuffer shortBuffer = ShortBuffer.allocate(samples.length);
playTask = new PlayingTask(Main2Activity.this,shortBuffer,numOfSamples);
}
});
recordSlideBar
ist eine benutzerdefinierte Ansicht, die ich schrieb, dass hat eine o nTouchListener in es recordSlideBar.setDownRun(Runnable)
setzt Runnable
auf MotionEvent.ACTION_DOWN
und recordSlideBar.setUpRun(Runnable)
setzt Runnable
auf MotionEvent.ACTION_UP
.
Grundsätzlich erstelle ich die AsyncTask und führen Sie es aus, wenn ACTION_DOWN
genannt wird und es aufheben, wenn ACTION_UP
genannt wird ...
Ich bin neu in der gesamten Audio-Capturing-Techniken, so dass Sie einige Fehler in meinem Code sehen könnte in Bezug auf das. Bitte beachten Sie, dass das Problem im Moment die AsyncTask ist;)
EDIT: Hier ist ein Druck-Bildschirm des Debugger-Panel, nachdem ich die Aufgabe abbrechen. feststellen, dass die AsyncTask Status WAIT und in der Registerkarte Variablen ist, mCancelled
ist true
und mStatus
Running
Screen-shot: asynctask status=wait,cancelled=true,status=running
Könnten Sie den Code hinzufügen, wo Sie diese Aufgabe starten und abbrechen ? –
Alles für dich :) –