Android应用中声音池的致命异常

时间:2013-07-12 16:48:41

标签: android soundpool

我正在开发一款游戏,它有一个摄像头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

有任何解决方案吗?

1 个答案:

答案 0 :(得分:1)

代码中没有soundpool的释放资源,这样做是非常重要的,以防止内存泄漏,这可能导致SoundPool在重新打开活动后崩溃......

问候!