我对Android中的UI线程有疑问:
我的活动扩展了AsyncTask以对wave文件进行一些计算。如果我运行一次应用程序,则需要大约15分钟才能完成。这对我来说不是问题。 我想多次启动这个过程(例如4次,因为我有4个波形文件)所以我希望时间为1小时(15分钟* 4 = 1小时),但事实并非如此,它持续约3个小时!
为了多次启动进程,我创建了一个调用" new ProcessTask()。execute();" 4次,我在" onPostExecute"
中调用此函数你有任何想法,为什么我多次运行需要更多时间?
提前感谢您的帮助
public void processingRespiratoryFiles() {
if(p<=MainActivity.count)
{
filePath = Environment.getExternalStorageDirectory() + "/external_sd/AudioRecorder/audio"+p+".wav";
File filein = new File(filePath);
if (filein.exists())
new ProcessTask().execute();
}
else
{
RespiratoryHandling(ODI_Sum,0);
Index.setText(Double.toString(ODI_Sum));
message2=ODI_Sum;
}
}
private class ProcessTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
@Override
protected Integer doInBackground(Void... params) {
return process(filePath);
}
@Override
protected void onPostExecute(Integer result) {////////////////////////////////////////////////////////
dialog.dismiss();
if (result > -1)
{
p++;
ODI=(double)result/NumberOfHours;
ODI_Sum+=ODI;
processingRespiratoryFiles();
}
}
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(
Diagnose.this, "Diagnosing, please wait",
"Processing...");
}
}
/**
* Reset ring buffer for filter process before filtering signal
* @param alength number of a coefficients
* @param blength number of a coefficients
*/
public void resetRingBuffer(int alength, int blength) {
xv = new double[blength + 1];
yv = new double[alength + 1];
px = 0;
py = 0;
}
/**
* Filter each second of signal and then compute the energy of output
* @param din input stream of audio file
* @param length number of read samples
* @param numChannels number of channels of signal
* @return energy value of 1 second filtered signal
*/
public double readEnergyFiltered(DataInputStream din, int length,
int numChannels) {
double energy = 0.0;
try {
byte[] byteBuffer = new byte[length * 2 * numChannels]; // 16 bit
// read length samples from file's stream
int r = din.read(byteBuffer); // bytes read
// if reach to end of file
if (r == -1)
return -1.0;
r = r / (2 * numChannels); // samples read
// apply the filter
for (int i = 0; i < r; ++i) {
// get the new sample
short sample = (short) ((byteBuffer[2 * numChannels * i] & 0xff) | (byteBuffer[2
* numChannels * i + 1] & 0xff) << 8);
xv[px] = (double) sample / 32768.0;
// compute the output
double y = bcoef[0] * xv[px];
for (int j = 1; j < bcoef.length; ++j)
y += bcoef[j] * xv[(px - j + xv.length) % xv.length];
for (int j = 1; j < acoef.length; ++j)
y -= acoef[j] * yv[(py - j + yv.length) % yv.length];
// save the result
yv[py] = y;
// update energy
energy += y * y;
// increment the index of the ring buffer
px = (px + 1) % xv.length;
py = (py + 1) % yv.length;
}
return energy;
} catch (Exception e) {
e.printStackTrace();
}
return -1.0;
}
/**
* Process the filtering, computing energy and estimating number of events
* @param filePath path to audio file on sd card
* @return number of events
*/
private int process(String filePath) {
try {
int event = 0;
double sum =0.0;
byte[] header = new byte[44];
File filein = new File(filePath);
FileInputStream fin = new FileInputStream(filein);
BufferedInputStream bin = new BufferedInputStream(fin);
DataInputStream din = new DataInputStream(bin);
din.read(header);
// Sample Rate
int fs = (header[24] & 0xff) | (header[25] & 0xff) << 8
| (header[26] & 0xff) << 16 | (header[27] & 0xff) << 24;
double Ts = 1.0 / fs;
Log.v("PERM", "Sample Rate: " + String.valueOf(fs));
// Num Channels
int numChannels = (header[22] & 0xff) | (header[23] & 0xff) << 8;
Log.v("PERM", "Num Channel: " + String.valueOf(numChannels));
// Bits Per Sample
int bitsPerSample = (header[34] & 0xff) | (header[35] & 0xff) << 8;
Log.v("PERM", "Bits per sample: " + String.valueOf(bitsPerSample));
// Sample Rate
int numBytes = (header[40] & 0xff) | (header[41] & 0xff) << 8
| (header[42] & 0xff) << 16 | (header[43] & 0xff) << 24;
int N = numBytes / numChannels / (bitsPerSample / 8);
Log.v("PERM", "Data Length: " + String.valueOf(N));
// Calibration phase
// Find average energy for the first 180 seconds
double energy = 0.0;
resetRingBuffer(acoef.length, bcoef.length);
for (int i = 0; i < 30; i++) {
sum = readEnergyFiltered(din, fs, numChannels);
energy += sum * Ts;
}
if(MainActivity.count==1)
{
mean_energy = energy / 30.0;
ThresholdR = 0.8 * mean_energy;
}
Log.v("PERM", "Threshold: " + String.valueOf(ThresholdR));
// process hold file
resetRingBuffer(acoef.length, bcoef.length);
din.close();
bin.close();
fin.close();
fin = new FileInputStream(filein);
bin = new BufferedInputStream(fin);
din = new DataInputStream(bin);
din.read(header);
N = N / fs;
int j = 1;
while (j <= N) {
int counter = 0;
//int trigger = 0;
energy = readEnergyFiltered(din, fs, numChannels) * Ts;
if (energy >= 0.) {
Log.v("PERM", "Energy " + String.valueOf(energy));
//while ((energy <= Threshold) || (trigger < 4))
while ((energy < ThresholdR)) {
counter++;
energy = readEnergyFiltered(din, fs, numChannels) * Ts;
Log.v("PERM", "Inner Energy " + String.valueOf(energy));
if (energy < 0)
break;
//trigger++;
}
}
if (counter > 10)
event++;
if (counter > 0)
j += counter;
else
j++;
}
Log.v("PERM", "Event: " + String.valueOf(event));
din.close();
bin.close();
fin.close();
return event;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
答案 0 :(得分:3)
这个真的需要在IntentService中完成。如果您使用AsyncTask并意外地翻转您的设备,您的Activity将重新启动并且AsyncTask将消失。 IntentService将允许您“移动”远离当前活动。
虽然,我不得不说,如果你愿意等待15分钟让AsyncTask完成,那么你的应用程序是不寻常的。