ANR Reason keyDispatchingTimedOut MediaPlayer

时间:2013-08-16 03:06:23

标签: android android-asynctask android-mediaplayer android-anr-dialog

在我的应用程序中,我有一个ListView的音乐项目,当我点击一个项目时,我获取其相应的mp3 URL以在我的MediaPlayer中流式传输。每次用户点击“播放”按钮时,我都会设置MediaPlayer的数据源。现在的问题是,当我单击“播放”按钮,然后滚动ListView时,屏幕会冻结,然后会打开一个对话框:

AppName is not responding.
Would you like to close it?
      Wait       OK

但我无法获得堆栈跟踪,但它说的是:

ANR my.package.name.AppName ...
Reason: keyDispatchingTimedOut

我已经阅读过将我的进程放在后台线程中,以避免UI线程等待。这是我目前的实施,但问题仍然存在:

Thread t = new Thread() {
            public void run() {
                SampleActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        try {
                            mp.reset();
                            mp.setDataSource(musicURI);
                            mp.prepare();
                            mp.start();

                            songSeekBar.setEnabled(true);

                            // Changing Button Image to stop image
                            btnPlay.setImageResource(R.drawable.btn_stop);

                            // set Progress bar values
                            songSeekBar.setProgress(0);
                            songSeekBar.setMax(100);

                            // Updating progress bar
                            updateProgressBar();
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (IllegalStateException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            songSeekBar.setEnabled(false);
                            songTotalDurationLabel.setText("0:00");
                            songCurrentDurationLabel.setText("0:00");
                            Log.d(Constant.TAG_SAMPLE, musicTitle
                                    + " mp3 file not found.");
                            e.printStackTrace();
                        }
                    }
                });
            }
        };
        t.start();

我所做的是在runOnUiThread内放置Thread(不工作),我只尝试Thread(不工作),并在其AsynctaskdoInBackground 1}}但播放器正在后台播放但无法停止,但我没有尝试将其放入onPostExecute

我有一种感觉我错过了什么。有一件事是肯定的,我应该把它放在后台线程中但是哪一个呢?任何想法都被接受了,谢谢!

修改 所以,我改变了我的实现,但它仍然存在:

Thread thread = new Thread() {
        public void run() {
            Handler refresh = new Handler(Looper.getMainLooper());
            refresh.post(new Runnable() {
                public void run() {
                    // Play song
                    try {
                        mp.reset();
                        mp.setDataSource(globalSongIndex);
                        mp.prepare();
                        mp.start();

                        songSeekBar.setEnabled(true);

                        // Changing Button Image to pause image
                        btnPlay.setImageResource(R.drawable.btn_stop);

                        // set Progress bar values
                        songSeekBar.setProgress(0);
                        songSeekBar.setMax(100);

                        // Updating progress bar
                        updateProgressBar();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        songSeekBar.setEnabled(false);
                        songTotalDurationLabel.setText("0:00");
                        songCurrentDurationLabel.setText("0:00");
                        Log.d(Constant.TAG_MYPAGE, musicTitle + " mp3 file not found.");
                        e.printStackTrace();
                    }
                }
            });
        }
    };
    thread.start();
顺便说一下,我把它建立在android网站here上。

2 个答案:

答案 0 :(得分:0)

好的,你的代码在主线程中执行。初始化播放器并不是一个好主意。完全没有改变从第一个代码到第二个代码的任何内容。

ANR出现在字符串player.prepare()中。尝试使用playerAsync而不是。它将准备播放器异步或你删除它:

Handler refresh = new Handler(Looper.getMainLooper());
        refresh.post(new Runnable() {
            public void run() {

并在后台线程中完成所有工作。

阅读有关AsyncTask的信息 - 这是一个在后台完成一些工作的好班级。比使用普通线程更有用。

正确的方式看起来像:

MediaPlayer mp = new MediaPlayer();
mp.setDataSource(YourURI);
mp.setOnPreparedListener(new OnPreparedListener() {
  public void onPrepared(MediaPlayer mp)
  {
   long duration = mp.getDuration();
   mp.start();
  }
});
mp.prepareAsync();

答案 1 :(得分:0)

我不能给你我的实现,对不起伙伴属于我的公司,我能告诉你的是你的线程删除了这个SampleActivity.this.runOnUiThread(new Runnable(){ 。你调用mp.start的那一刻创建另一个有这个ocode的线程

Thread.sleep(1000); 
SampleActivity.this.runOnUiThread(new Runnable() { 
public void run() {
                    // Update UI
                    try {

                        // Updating progress bar
                            updateProgressBar();
}};      

这将在一个线程中播放您的文件,然后让另一个线程休眠1秒钟然后调用主线程中的方法来更新UI