0

我正在尝试编写一个简单的应用程序来尝试加载和播放声音文件。我有两种声音,我想得到它们的列表,然后播放任何被点击的声音。以下代码有效:

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);
        }
    }

它运行良好,按预期单击时会更改文本。我无法理解这种行为。

4

2 回答 2

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!");
        }
    }
于 2012-12-03T09:13:11.673 回答
0

问题可能是 不维护创建的所有子视图super.getListView().getChildAt(i);ListView它只保留对屏幕上视图的引用。屏幕外的视图被回收并重新用于其他内容。如果基础数据很大,这避免了必须管理数百个视图。

getView()尝试从适配器中的方法加载声音。一般来说,避免试图ListView从外面抓住物品getView()

于 2012-12-03T04:32:22.060 回答