#android #stack-overflow
#Android #переполнение стека
Вопрос:
Я создаю код для вычисления bpm для медиафайлов. мое требование заключается в том, что я должен воспроизводить песню только в течение 5 секунд, не более 5 секунд. итак, я использую Thread.sleep(5000) и вызываю обработчик message. это вызывает исключение java.long.stackoverflowexception.
мой код:
currentThread.start();
....
public void run() {
try {
Log.e("bpm", "in run method");
BPM2SampleProcessor processor = new BPM2SampleProcessor();
processor.setSampleSize(1024);
EnergyOutputAudioDevice output = new EnergyOutputAudioDevice(processor);
output.setAverageLength(1024);
try {
player = new Player(new FileInputStream("/sdcard/taxi.mp3"), output); // line no 40
currentThread.run(); // line no 41
player.play();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JavaLayerException e) {
e.printStackTrace();
}
text.setText("bpm is " processor.getBPM());
Log.e("bpm"," bpm is " processor.getBPM());
Thread.sleep(5000);
threadHandler.sendEmptyMessage(0);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Handler threadHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
Log.e("calledThread","5seconds");
player.close();
}
};
журнал cat:
05-20 18:05:01.761: ERROR/AndroidRuntime(2777): Uncaught handler: thread Thread-8 exiting due to uncaught exception
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): java.lang.StackOverflowError
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:49)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:45)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.ReadWriteHeapByteBuffer.<init>(ReadWriteHeapByteBuffer.java:49)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.BufferFactory.newByteBuffer(BufferFactory.java:51)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.ByteBuffer.allocate(ByteBuffer.java:54)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:351)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.nio.charset.Charset.encode(Charset.java:711)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.lang.String.getBytes(String.java:1022)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at org.apache.harmony.luni.util.Util.getBytes(Util.java:61)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.io.File.properPath(File.java:1362)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.io.FileInputStream.<init>(FileInputStream.java:77)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.io.FileInputStream.<init>(FileInputStream.java:130)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at beatit.beatit.main2.run(main2.java:40)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.lang.Thread.run(Thread.java:1096)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at beatit.beatit.main2.run(main2.java:41)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.lang.Thread.run(Thread.java:1096)
05-20 18:05:02.237: ERROR/AndroidRuntime(2777): at java.la
05-20 18:05:05.573: ERROR/JavaBinder(1276): !!! FAILED BINDER TRANSACTION !!!
Ответ №1:
Ваш поток снова и снова вызывает метод run, вызывая stackoverflow:
currentThread.run();
Нет условия, чтобы остановить это. (Просто чтобы было понятно, currentThread.start()
вызывает метод run на некотором этапе)
Комментарии:
1. вам лучше сделать. почему оно там на первом месте?
2. после удаления
currentThread.run();
песня воспроизводится непрерывно. не останавливается через 5 секунд. что делать для остановки? пожалуйста, помогите мне.3. добавьте режим ожидания еще на 1 секунду после отправки сообщения обработчику. Это должно сработать, к сожалению, у меня нет Android, чтобы протестировать его сейчас.
4. Thread.sleep (5000); threadHandler.sendEmptyMessage(0); Thread.sleep (1000); я сделал вышеуказанное кодирование. но я получаю следующую ошибку: пожалуйста, помогите мне android.view.ViewRoot$CalledFromWrongThreadException: Только исходный поток, который создал иерархию представлений, может касаться своих представлений.
5. трудно точно сказать, что вы должны делать без дополнительного кода, но любая операция с графическим интерфейсом должна выполняться в потоке GUI (main). посмотрите на AsyncTask, это может вам помочь —> developer.android.com/reference/android/os/AsyncTask.html
Ответ №2:
Вы почти ответили сами:
currentThread.run(); // line no 41
Ниже я написал пример, как справиться с вашей проблемой:
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
//put your code here
}
};
try {
task.execute((Void)null).get(5, TimeUnit.SECONDS);
} catch(Exception e) {
e.printStackTrace();
}
Комментарии:
1.после удаления
currentThread.run();
песня воспроизводится непрерывно. не останавливается через 5 секунд. что делать для остановки? пожалуйста, помогите мне.