исключение переполнения стека в потоке на Android

#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 секунд. что делать для остановки? пожалуйста, помогите мне.