我正在开发一款游戏,它有一个摄像头surfaceView和一个播放火焰声的按钮。几次启动活动后应用程序崩溃了。堆栈跟踪显示soundpool中的错误 这是我的代码:
public class MainActivity extends Activity implements SurfaceHolder.Callback,OnClickListener {
Camera mCamera;
SurfaceView mPreview;
Button shoot;
TextView rounds;
int shootsound;
int reloadsound;
SoundPool spool;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null) {
int btnNumber = extras.getInt("button");
switch(btnNumber)
{
case 1 : setContentView(R.layout.activity_main); break;
case 2 : setContentView(R.layout.machinegun); break;
}
}
// Ads
new TapContextSDK(getApplicationContext()).initialize();
new TapContextSDK(getApplicationContext()).showAd();
mPreview = (SurfaceView)findViewById(R.id.preview);
mPreview.getHolder().addCallback(this);
mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera = Camera.open();
shoot=(Button)findViewById(R.id.button1);
shoot.setOnClickListener(this);
rounds=(TextView)findViewById(R.id.textView1);
//SOUND POOL
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
spool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
shootsound= spool.load(this, R.raw.shoot, 2);
reloadsound= spool.load(this, R.raw.reload, 2);
}
@Override
public void onPause() {
super.onPause();
mCamera.stopPreview();
}
@Override
public void onDestroy() {
super.onDestroy();
mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Parameters parameters = mCamera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
Camera.Size previewSize = previewSizes.get(4); //480h x 720w
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(parameters);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0) {
mCamera.setDisplayOrientation(90);
} else if(display.getRotation() == Surface.ROTATION_270) {
mCamera.setDisplayOrientation(180);
}
mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mPreview.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("PREVIEW","surfaceDestroyed");
}
//shoot sound
public void shoot(){
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float volume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
spool.play(shootsound, volume, volume, 1, 0, 1f);
}
//reload sound
public void reload(){
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float volume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
spool.play(reloadsound, volume, volume, 1, 0, 1f);
}
//Vibrate
public void vibrateMe() {
Vibrator vibrate = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrate.vibrate(100);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()) {
case R.id.button1:
int tmp = Integer.valueOf( rounds.getText().toString());
if(tmp==0)
{
rounds.setText("12");
reload();
}
else
{
shoot();
vibrateMe();
rounds.setText( String.valueOf( tmp-1) );
}
break;
}
}
}
堆栈跟踪:
07-12 19:37:40.320: D/dalvikvm(10448): GC_FOR_ALLOC freed 4034K, 13% free 56729K/64612K, paused 37ms, total 37ms
07-12 19:37:40.350: I/dalvikvm-heap(10448): Grow heap (frag case) to 62.091MB for 6991888-byte allocation
07-12 19:37:40.501: D/dalvikvm(10448): GC_FOR_ALLOC freed 0K, 12% free 63557K/71444K, paused 30ms, total 30ms
07-12 19:37:40.811: E/AndroidRuntime(10448): FATAL EXCEPTION: FinalizerWatchdogDaemon
07-12 19:37:40.811: E/AndroidRuntime(10448): java.util.concurrent.TimeoutException: android.media.SoundPool.finalize() timed out after 10 seconds
07-12 19:37:40.811: E/AndroidRuntime(10448): at android.media.SoundPool.release(Native Method)
07-12 19:37:40.811: E/AndroidRuntime(10448): at android.media.SoundPool.finalize(SoundPool.java:485)
07-12 19:37:40.811: E/AndroidRuntime(10448): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
07-12 19:37:40.811: E/AndroidRuntime(10448): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
07-12 19:37:40.811: E/AndroidRuntime(10448): at java.lang.Thread.run(Thread.java:856)
07-12 19:37:41.281: I/PREVIEW(10448): surfaceDestroyed
有任何解决方案吗?
答案 0 :(得分:1)
代码中没有soundpool的释放资源,这样做是非常重要的,以防止内存泄漏,这可能导致SoundPool在重新打开活动后崩溃......
问候!