MediaPlayer变量的最大数量

时间:2012-04-23 19:45:44

标签: android

我正在为Android做一个非常简单的应用程序,但我遇到了一个问题,我真的不知道如何解决。 我的应用程序有一个带有8个按钮的布局,当你点击它时,每个按钮都发出声音。 我只有一个活动,在oncreate方法中我定义了8个MediaPlayer变量,这是我原始文件夹上的mp3格式的8种不同声音。然后我将它们与每个按钮相关联。 当我在模拟器上编译应用程序时,一切正常,但是当我在手机上编译时,声音8不起作用。我的意思是,当我按下一个与声音8相关联的按钮时,应用程序崩溃了。我还注意到,如果我添加更多带有更多声音的按钮,只有前7个声音可以正常工作,而其他声音则会让应用程序崩溃。好像我不能拥有超过七个MediaPlayer变量。但这没有任何意义,是吗?

任何人都可以帮我解决这个问题吗?

提前致谢。

这是我的java代码:

package com.f22rumaj.org;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MyMain extends Activity {
/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //set up the button sound
    final MediaPlayer mpBoton1 = MediaPlayer.create(this, R.raw.button1); 
    final MediaPlayer mpBoton2 = MediaPlayer.create(this, R.raw.button2); 
    final MediaPlayer mpBoton3 = MediaPlayer.create(this, R.raw.button3); 
    final MediaPlayer mpBoton4 = MediaPlayer.create(this, R.raw.button4); 
    final MediaPlayer mpBoton5 = MediaPlayer.create(this, R.raw.button5); 
    final MediaPlayer mpBoton6 = MediaPlayer.create(this, R.raw.button6); 
    final MediaPlayer mpBoton7 = MediaPlayer.create(this, R.raw.button7); 
    final MediaPlayer mpBoton8 = MediaPlayer.create(this, R.raw.button8);


    Button boton1=  (Button) findViewById(R.id.button_1);
    Button boton2=  (Button) findViewById(R.id.button_2);
    Button boton3=  (Button) findViewById(R.id.button_3);
    Button boton4=  (Button) findViewById(R.id.button_4);
    Button boton5=  (Button) findViewById(R.id.button_5);
    Button boton6=  (Button) findViewById(R.id.button_6);
    Button boton7=  (Button) findViewById(R.id.button_7);
    Button boton8=  (Button) findViewById(R.id.button_8);

    boton1.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton1.start();

        }
    });

    boton2.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton2.start();

        }
    });

    boton3.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton3.start();

        }
    });

    boton4.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton4.start();

        }
    });

    boton5.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton5.start();

        }
    });

    boton6.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton6.start();

        }
    });

    boton7.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton7.start();

        }
    });

    boton8.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mpBoton8.start();

        }
    });

}
}

3 个答案:

答案 0 :(得分:2)

哇!您不应该创建多个MediaPlayer实例。巨大的资源浪费以及可能导致崩溃的原因。你没说,但我想这是一个记忆问题。将来,请包含logcat输出或崩溃的堆栈跟踪。

看一下SoundPool类。

http://developer.android.com/reference/android/media/SoundPool.html

网上有很多例子。例如

http://www.techrepublic.com/blog/app-builder/getting-your-feet-wet-in-androids-soundpool/877

答案 1 :(得分:1)

  1. 请考虑使用SoundPool
  2. 如果你有很多项目,他们的名字被编入索引,你应该将它们放在地图中。这样您就可以避免为每个按钮创建单独的侦听器。例如:

    Map<Button, MediaPlayer> buttonMap = new HashMap<Button, MediaPlayer>();
    map.put((Button)findViewById(R.id.button_1), MediaPlayer.create(this, R.raw.button1));
    // same for the rest
    
    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MediaPlayer selected = buttonMap.get(v);
            selected.start();
        }
    };
    for (Button b : buttonMap.keySet()) {
        b.setOnClickListener(listener);
    }
    

答案 2 :(得分:0)

是的,绝对不应该使用MediaPlayer的那么多实例,但是开始时很容易犯错误。使用单个MediaPlayer实例来考虑这样的事情:

MediaPlayer mediaPlayer = new MediaPlayer();

int[] buttonIds = { R.id.button_1, R.id.button_2, R.id.button_3,
    R.id.button_4, R.id.button_5, R.id.button_6, R.id.button_7,
    R.id.button_8 };

int[] soundIds = { R.raw.button1, R.raw.button2, R.raw.button3,
    R.raw.button4, R.raw.button5, R.raw.button6, R.raw.button7, 
    R.raw.button8 };

int size = buttonIds.length;

for(int i = 0; i < size; i++) {
    (Button)findViewById(buttonIds[i]).setOnClickListener(
            new View.OnClickListener() {
        @Override public void onClick(View v) {
            if(mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.reset();
            AssetFileDescriptor afd = 
                getResources().openRawResourceFd(soundIds[i]);
            mediaPlayer.setDataSource(afd.getFileDescriptor(), 
                afd.getStartOffset(), afd.getLength());
            mediaPlayer.prepare();
            mediaPlayer.start();
        }
    }
}

考虑一下伪代码,因为我没有测试它(虽然它应该很接近),并且只是采取这个想法。保留一组按钮ID和一组声音ID(将它们编入索引,即按钮ID 1应与声音ID 1位于同一位置)。对于每个按钮ID,找到View,将其转换为Button,然后添加重置播放器的onClickListener(如果正在播放),将数据源设置为关联的声音ID,准备播放器并启动它。

作为一般规则,每当你看到自己重复这样的代码时,你应该寻找更好的设计来避免它。