我的应用程序在屏幕上有一个球。当球在中途时,应用程序会记录一些音频,计算FFT并进行一些额外的分析。
这是由Asynctask处理的,但是动画仍然会短暂停顿。
有没有人对如何让它运行更顺畅有任何建议?
由于
以下代码:
import com.ben.applicationLayer.GameView;
import dataObjectLayer.Sprite;
import dataObjectLayer.MusicalNote;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import android.media.AudioFormat;
import android.os.AsyncTask;
public class recorderThread extends AsyncTask<Sprite, Void, Integer> {
short[] audioData;
int bufferSize;
Sprite ballComp;
@Override
protected Integer doInBackground(Sprite... ball) {
MusicalNote note = ball[0].expectedNote;
ballComp = ball[0];
boolean recorded = false;
double frequency;
int sampleRate = 8192;
AudioRecord recorder = instatiateRecorder(sampleRate);
double[] magnitude = new double[1024];
double[] audioDataDoubles = new double[2048];
while (!recorded) { //loop until recording is running
if (recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED)
// check to see if the recorder has initialized yet.
{
if (recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)
recorder.startRecording();
//check to see if the Recorder has stopped or is not recording, and make it record.
else {
double max_index;
recorder.read(audioData,0,bufferSize);
//read the PCM audio data into the audioData array
computeFFT(audioDataDoubles, magnitude);
max_index = getLargestPeakIndex(magnitude);
frequency = getFrequencyFromIndex(max_index, sampleRate);
//checks if correct frequency, assigns number
int correctNo = correctNumber(frequency, note);
checkIfMultipleNotes(correctNo, max_index, frequency, sampleRate, magnitude, note);
if (audioDataIsNotEmpty())
recorded = true;
if (correctNo!=1)
return correctNo;
}
}
else
{
recorded = false;
recorder = instatiateRecorder(sampleRate);
}
}
if (recorder.getState()==android.media.AudioRecord.RECORDSTATE_RECORDING)
{
killRecorder(recorder);
}
return 1;
}
private void killRecorder(AudioRecord recorder) {
recorder.stop(); //stop the recorder before ending the thread
recorder.release(); //release the recorders resources
recorder=null; //set the recorder to be garbage collected
}
@Override
protected void onPostExecute(Integer result) {
(result == 2)
GameView.score++;
}
private AudioRecord instatiateRecorder(int sampleRate) {
bufferSize= AudioRecord.getMinBufferSize(sampleRate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT)*2;
//get the buffer size to use with this audio record
AudioRecord recorder = new AudioRecord (AudioSource.MIC,sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,bufferSize); //instantiate the AudioRecorder
audioData = new short [bufferSize]; //short array that pcm data is put into.
return recorder;
}
}
答案 0 :(得分:3)
使用Asynctask就像你想要做的那样。但是,我建议使用线程池。然后,您可以将动画作为任务添加,将录音添加为任务,将FFT作为另一项任务添加,将附加分析作为任务添加。
简短的口吃可能是在动画线程中为录制分配资源的结果。使用池意味着您在创建运行音频任务的线程时不必暂停。显然,一些代码可以很方便地完全理解你的问题。
看看:
的ScheduledThreadPoolExecutor http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
或
的ThreadPoolExecutor http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
您可能想要做的一个非常简单的示例:
在您的活动中,您可以定义此项以启动任务
ExecutorService threadPool = new ScheduledThreadPoolExecutor(2);
Recording record = new Recording();
Ball ball = new Ball(threadPool, record);
threadPool.submit(ball);
Ball.java
import java.util.concurrent.ExecutorService;
public class Ball implements Runnable {
private final Recording record;
private final ExecutorService threadPool;
private boolean condition;
private boolean active;
public Ball(ExecutorService threadPool, Recording record) {
this.record = record;
this.threadPool = threadPool;
this.active = true;
}
@Override public void run() {
while (this.active) {
moveBall();
if (isBallHalfway()) {
threadPool.submit(record);
}
}
}
private boolean isBallHalfway() {
return condition; // Condition for determining when ball is halfway
}
private void moveBall() {
// Code to move the ball
}
}
Recording.java
public class Recording implements Runnable {
@Override public void run() {
// Do recording tasks here
}
}
答案 1 :(得分:1)
正如穆罕默德所说,如果没有看到代码,很难猜出问题可能是什么。考虑到这一点......
听起来你的AsyncTask
可能阻止其他线程执行。确保你在那里有一些Thread.sleep()
的调用,让调度程序有机会切换回UI线程(Thread.yield()
也是一个选项,但要注意有一些收益率的问题)。
答案 2 :(得分:0)
没有代码,很难猜到可以优化,但我会告诉你我在加载时做了100多万次操作。 •如果您遇到性能问题,请尝试: 1 - 检查你的数据类型的变量,并设置较低,以防你确定变量不需要更多的字节,即大小你短而不是int。
2 - 检查您的代码并尝试将所有结果存储起来以便下次启动,并在下次调用它们而不是再次计算它们。
•但是如果你的问题是动画很慢并且你没有内存问题,那么试着减少动画时间或增加动作单位。
顺便说一下你如何实现动画?逐帧动画,布局动画或视图动画?