在我的应用程序中,我有一个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
(不工作),并在其Asynctask
内doInBackground
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上。
答案 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