我正在为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();
}
});
}
}
答案 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)
SoundPool
。如果你有很多项目,他们的名字被编入索引,你应该将它们放在地图中。这样您就可以避免为每个按钮创建单独的侦听器。例如:
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,准备播放器并启动它。
作为一般规则,每当你看到自己重复这样的代码时,你应该寻找更好的设计来避免它。