gc освободил объекты xxxx и затем заморозил приложение

Я пытаюсь создать простое приложение, которое содержит десять видов деятельности. Каждое действие выглядит примерно одинаково, оно имеет четыре кнопки (разного цвета), и при нажатии одной конкретной кнопки открывается следующее действие. В методе OnCreate каждого действия есть медиаплеер, который воспроизводит название этого действия. Через некоторое время я вижу в LogCat, что gc освободил некоторые объекты, и в это время Activity не воспроизводит звук, а кнопки отключены.

Есть ли у вас какие-либо советы или предложения, как это решить?

Вот код одного занятия:

public class Green extends Activity {

int buttonActive = 0;
int buttonWrong = 0;
MediaPlayer player;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_green);

    buttonWrong = 0;
    playSound();

    Button btn = (Button)findViewById(R.id.button1);
    Button btn2 = (Button)findViewById(R.id.button2);
    Button btn3 = (Button)findViewById(R.id.button3);
    Button btn4 = (Button)findViewById(R.id.button4);

    btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(buttonActive == 1){

            playSoundCorrect();
            Intent intent = new Intent(v.getContext(),Blue.class);
            startActivity(intent);
            }
        }
    });

    btn2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if(buttonActive == 1 && buttonWrong == 0){
                buttonWrong = 1;
                playSoundWrong();
            }           
        }
    });

btn3.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if(buttonActive == 1 && buttonWrong == 0){
                buttonWrong = 1;
                playSoundWrong();
            }           
        }
    });

btn4.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        if(buttonActive == 1 && buttonWrong == 0){
            buttonWrong = 1;

            playSoundWrong();
        }       
    }
});

}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}


private void playSound(){

    MediaPlayer player = MediaPlayer.create(this, R.raw.green);
    player.start(); 
    player.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
            buttonActive = 1;
        }
    });
}

private void playSoundWrong(){

player = MediaPlayer.create(this, R.raw.wrong2);

if(!player.isPlaying()){
    player.start();

}

player.setOnCompletionListener(new OnCompletionListener() {

    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        buttonWrong = 0;
    }
});

}

private void playSoundCorrect(){

MediaPlayer player = MediaPlayer.create(this, R.raw.correct);
player.start();
player.setOnCompletionListener(new OnCompletionListener() {

    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.release();
    }
});
}
}

1 ответ

Решение

Это выглядит как в private void playSound ты маскируешь класс player имущество. Если вы говорите player = MediaPlayer.create тогда класс player свойство будет установлено на новый MediaPlayer, и игрок будет доступен, пока класс доступен. Вместо этого вы говорите MediaPlayer player = MediaPlayer.create, который создает новый player переменная, которая ограничена до playSound метод - как только метод завершает player больше недоступен и будет собирать мусор, даже если класс все еще доступен.

Другие вопросы по тегам