Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android AsyncTask isCancelled()返回true,但doInBackground不返回';t端_Android_Android Asynctask - Fatal编程技术网

Android AsyncTask isCancelled()返回true,但doInBackground不返回';t端

Android AsyncTask isCancelled()返回true,但doInBackground不返回';t端,android,android-asynctask,Android,Android Asynctask,我有一个录制音频的任务。问题是一旦我从UI线程调用cancel(true),isCancelled()返回true(就像它应该返回的那样),但是doInBackground函数保持运行,如果我运行getStatus()在AsyncTask上,它返回RUNNING,并且onCancelled方法都不被称为nore doesonPostExecute 由于(!isCancelled())时,所有doInBackground代码都放在中,因此一旦任务取消,该方法应该结束 调用AsyncTask.can

我有一个录制音频的任务。问题是一旦我从UI线程调用
cancel(true)
isCancelled()
返回
true
(就像它应该返回的那样),但是
doInBackground
函数保持运行,如果我运行
getStatus()
在AsyncTask上,它返回RUNNING,并且
onCancelled
方法都不被称为nore does
onPostExecute

由于(!isCancelled())时,所有
doInBackground
代码都放在
中,因此一旦任务取消,该方法应该结束

调用AsyncTask.cancel()后,while(!isCancelled())循环结束。我认为问题在于没有调用
returnnull
,这就是
doInBackground
没有结束的原因。。。但我可能错了

代码:

recordSlideBar
是我编写的一个自定义视图,其中有一个onTouchListener,而
recordSlideBar.setDownRun(Runnable)
MotionEvent.ACTION\u DOWN
recordSlideBar.setUpRun(Runnable)
MotionEvent.ACTION\u UP
设置一个
Runnable

基本上,我创建AsyncTask并在调用
ACTION\u DOWN
时执行它,在调用
ACTION\u UP
时取消它

我对整个音频捕获技术都是新手,所以您可能会在我的代码中看到一些关于这方面的错误。请记住,现在的问题是AsyncTask;)

编辑:这是我取消任务后调试器面板的打印屏幕。请注意,AsyncTask状态为WAIT,在变量选项卡中,
mCancelled
true
mStatus
正在运行


中可能会阻止
读取功能

int numberOfShort=record.read(audioBuffer,0,audioBuffer.length)

因此,
而(!isCancelled())
可能永远不会被调用

您可以将
Log.d()
放入
while
中,以检查代码是否被阻止,如


而(!isCancelled())
{
Log.d(“RECTASK”,“开始读取”);
int numberOfShort=record.read(audioBuffer,0,audioBuffer.length);
numSample+=numberOfShort;
Log.d(“RECTASK”,“end read”);
}

它被卡住了,因为使用的
AudioRecord.read()
方法是一个阻塞调用,它在本机级别而不是Java级别阻塞。因此,作为
AsyncTask.cancel()
的一部分发送的“中断”将无效。不要使用此版本的
read()
,而是使用采用
readMode
参数的版本,并将其设置为
read\u NON\u BLOCKING
。然后,您的循环将需要处理部分读取(以及实际处理数据-现在它只是将数据读取到一个方法本地数组中!)

您可以在开始此任务的位置添加代码并取消它吗?您可以做任何事情:)尝试您的解决方案。还是一样的问题。isCancelled()变为true,但doInBackground仍在运行。如果将其设置为非阻塞,则不应发生这种情况。运行时,查看线程堆栈,并查看异步任务线程在
doInBackground()
方法中的位置。我现在看到异步任务的状态正在等待,但我不明白为什么。。。如果你介意看一下我添加的屏幕截图并给出你的意见,那就太好了!这实际上是主线程在等待取消
AsyncTask
。您需要查看应用程序进程的所有线程列表,并找到运行您的任务的
AsyncTask
线程(它将被标记为这样的名称)。我在while循环中已经有一个Log.d,它工作正常(日志一次又一次地出现,直到isCancelled()变为true,循环结束)。我删除了日志,因为它使我的logcat崩溃…@AlonLevy
log.d(“RECTASK”,“after while\niscalled=“+isCancelled())这是在取消后调用的吗?是。我编辑了这个问题,并解释了while(isCancelled())循环以它结束should@AlonLevy有些事你应该知道。取消任务后,任务的状态将保持为
PENDING
RUNNING
。取消任务后,状态不会更改。您应该同时检查状态和
isCanceled()
。很高兴知道这一点!但是它并没有真正解决我的问题,因为我确实检查任务
是否已取消()
,并且它返回
true
。我添加了一个屏幕截图,显示了任务的变量:)
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;
    }

}
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);

            }
        });