我正在尝试编写一个简单的应用程序来尝试加载和播放声音文件。我有两个声音,我想得到它们的列表,然后回放点击的任何一个。以下代码有效:
public class SoundPoolTest extends ListActivity {
String sounds[] = { "shot", "explode" };
SoundPool soundPool;
int[] soundId = new int[sounds.length];
{
for (int i = 0; i < soundId.length; i++) {
soundId[i] = -1;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, sounds));
for (int i = 0; i < sounds.length; i++) {
try {
AssetManager assetManager = getAssets();
AssetFileDescriptor descriptor = assetManager.openFd("sound/"
+ sounds[i] + ".wav");
soundId[i] = soundPool.load(descriptor, 1);
} catch (IOException e) {
TextView textView = (TextView) super.getListView()
.getChildAt(i);
textView.setText("Could not load file!");
}
}
}
protected void onListItemClick(ListView list, View view, int position,
long id) {
super.onListItemClick(list, view, position, id);
if (soundId[position] != -1) {
soundPool.play(soundId[position], 1, 1, 0, 0, 1);
}
}
}
但是,如果我弄乱assetManager.openFd
的参数以便找不到文件来测试异常处理程序,则应用程序强制在呈现列表之前关闭(LogCat输出thread exiting with uncaught exception
)。问题是textView.setText("Could not load file!");
行;如果我评论它没有问题。更令人费解的是,如果我将catch
留空并将相同的代码放入onListItemClick
方法,那么它看起来像这样
protected void onListItemClick(ListView list, View view, int position,
long id) {
super.onListItemClick(list, view, position, id);
TextView textView = (TextView) super.getListView().getChildAt(position);
textView.setText("Clicked!");
if (soundId[position] != -1) {
soundPool.play(soundId[position], 1, 1, 0, 0, 1);
}
}
它运行正常,在按预期点击时更改文本。我无法理解这种行为。
答案 0 :(得分:0)
问题可能是super.getListView().getChildAt(i);
ListView
不会维护所有创建的子视图。它仅保留对屏幕上视图的引用。屏幕外的视图将被回收并重新用于其他内容。如果底层数据很大,这就避免了必须管理数百个视图。
尝试从适配器中的getView()
方法加载声音。一般情况下,请避免尝试暂停ListView
以外的getView()
项目。
答案 1 :(得分:0)
在你的for()循环中进行此更改,然后尝试。
for (int i = 0; i < sounds.length; i++) {
try {
AssetManager assetManager = getAssets();
AssetFileDescriptor descriptor = assetManager.openFd("sound/"
+ sounds[i] + ".wav");
TextView textView = (TextView) super.getListView()
.getChildAt(i);
soundId[i] = soundPool.load(descriptor, 1);
} catch (IOException e) {
textView.setText("Could not load file!");
}
}