Проблема с Try and Catch на Android
Как только я выполню приведенный ниже код, медиа проигрывается в течение 60 секунд, и мое приложение закрывается с ошибкой "К сожалению, YourAPP остановлен"., Если я удаляю "bv.setImageResource(R.drawable.play);" В конце концов, приложение работает отлично.
В чем проблема с bv.setImageResource (R.drawable.play) в блоке finally?
Это мой код
bv = (ImageButton) findViewById(R.id.imageButton1);
private void mpsleep() {
mp.start();
Thread timer= new Thread(){
public void run(){
try{
for (i =1;i<60;i++){
sleep(1000);//1 second pause
}
}catch(Exception e){
e.printStackTrace();
}finally{
mp.pause();
mp.seekTo(0);
bv.setImageResource(R.drawable.play);
}
}
};
timer.start();
}
LogCat
03-06 11:03:39.743: V/MediaPlayer(31802): message received msg=4, ext1=0, ext2=0
03-06 11:03:39.743: V/MediaPlayer(31802): Received seek complete
03-06 11:03:39.743: V/MediaPlayer(31802): All seeks complete - return to regularly scheduled program
03-06 11:03:39.743: V/MediaPlayer(31802): callback application
03-06 11:03:39.743: V/MediaPlayer(31802): back from callback
03-06 11:03:39.743: E/MediaPlayer(31802): mOnSeekCompleteListener is null. Failed to send MEDIA_SEEK_COMPLETE message.
03-06 11:03:40.918: V/MediaPlayer(31802): isPlaying: 1
03-06 11:03:40.918: V/MediaPlayer-JNI(31802): isPlaying: 1
03-06 11:03:40.918: V/MediaPlayer-JNI(31802): pause
03-06 11:03:40.918: V/MediaPlayer(31802): pause
03-06 11:03:40.923: V/MediaPlayer-JNI(31802): seekTo: 0(msec)
03-06 11:03:40.923: V/MediaPlayer(31802): seekTo 0
03-06 11:03:40.923: V/MediaPlayer(31802): getDuration
03-06 11:03:40.923: V/MediaPlayer(31802): message received msg=4, ext1=0, ext2=0
03-06 11:03:40.923: W/dalvikvm(31802): threadid=11: thread exiting with uncaught exception (group=0x40c541f8)
03-06 11:03:40.923: V/MediaPlayer(31802): Received seek complete
03-06 11:03:40.923: V/MediaPlayer(31802): All seeks complete - return to regularly scheduled program
03-06 11:03:40.923: V/MediaPlayer(31802): callback application
03-06 11:03:40.923: V/MediaPlayer(31802): back from callback
03-06 11:03:40.928: E/MediaPlayer(31802): mOnSeekCompleteListener is null. Failed to send MEDIA_SEEK_COMPLETE message.
03-06 11:03:40.953: E/AndroidRuntime(31802): FATAL EXCEPTION: Thread-20100
03-06 11:03:40.953: E/AndroidRuntime(31802): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4286)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:885)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.view.View.requestLayout(View.java:12881)
03-06 11:03:40.953: E/AndroidRuntime(31802): at android.widget.ImageView.setImageResource(ImageView.java:316)
03-06 11:03:40.953: E/AndroidRuntime(31802): at com.hello.YourApp.MainActivity.stopsound(MainActivity.java:118)
03-06 11:03:40.953: E/AndroidRuntime(31802): at com.hello.YourApp.MainActivity$6.run(MainActivity.java:143)
03-06 11:03:46.068: D/OpenGLRenderer(31802): Flushing caches (mode 0)
3 ответа
Сообщение об исключении говорит это ясно:
android.view.ViewRootImpl $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений.
Вы не можете получить доступ к элементам пользовательского интерфейса из отдельного потока. Удалить
setImageResource(R.drawable.play)
от run()
,
Если есть небольшой код (внутри класса Activity), который нужно запустить в потоке пользовательского интерфейса, вы можете использовать этот метод в Activity:
runOnUiThread(new Runnable(){
@override
public void run(){
//-- put code here--
}
});
Используйте поток пользовательского интерфейса, как я показал в следующем фрагменте кода,
bv = (ImageButton) findViewById(R.id.imageButton1);
private void mpsleep() {
mp.start();
Thread timer= new Thread(){
public void run(){
try{
for (i =1;i<60;i++){
sleep(1000);//5 second pause
}
}catch(Exception e){
e.printStackTrace();
}finally{
mp.pause();
mp.seekTo(0);
runOnUiThread(new Runnable() {
@Override
public void run() {
bv.setImageResource(R.drawable.play);
}
});
}
}
};
timer.start();
}
Explaination:
-> Вы могли бы написать bv = (ImageButton) findViewById(R.id.imageButton1);
внутри вашего onCreate
или же onResume
метод, который работает на Main thread(UI thread)
,
-> Вы создали новую тему Thread timer= new Thread()
и пытается манипулировать компонентом bv
.но bv
привязан к Main Thread(UI thread)
. Так что у вас возникли проблемы. Чтобы решить ее, просто используйте runOnUiThread(new Runnable)
метод.
Я надеюсь, что это будет полезно!
Используйте обработчик для запуска вашего кода bv.setImageResource(R.drawable.play);