OnBackPressed, чтобы убить обработчик в рамках действия - Android

Как вы можете видеть, у меня есть эта функция PlayLesson_01, которая одновременно отображает изображения и аудио. В этом упражнении есть два обработчика: один для управления изображениями и аудио, а другой - для завершения урока и возврата к предыдущему действию (меню уроков).

Цель. Нажмите кнопку "Жесткий диск", чтобы вернуться к предыдущему действию и прекратить воспроизведение изображений и звука.

Проблема. Когда я нажимаю на жесткий "Назад", я могу вернуться к предыдущему действию, но звук все еще играет. Я не могу остановить или убить обработчик, запущенный в рамках действия.

Вопрос. Как я могу полностью убить или остановить эти обработчики?

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.ViewSwitcher.ViewFactory;

public class PlayLesson_01 extends Activity implements OnItemSelectedListener,
    ViewFactory, Runnable {

// Setting up images
// Keeping all Images in array references to our images
public Integer[] mThumbIds = { R.drawable.nouraniyah,
        R.drawable.back_angle, R.drawable.back_fox, R.drawable.back_apple,
        R.drawable.back_twitter, R.drawable.back_thunderbird };
// setting up music
int[] myMusic = { R.raw.button_3, R.raw.button_3, R.raw.button_3,
        R.raw.button_3, R.raw.button_3, R.raw.button_3 };
int mNext;
private ImageSwitcher mSwitcher;
MediaPlayer mp;
Handler mHandlerWholeLesson = new Handler();
Runnable mRunnableWholelesson = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        startActivity(new Intent("com.example.AmazingGame.LESSONONE"));
    }
};

Handler mHandlerNextfile = new Handler();
Runnable mRunnableNextFile = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        mp.setOnCompletionListener(mListener);
        mp.start();
    }

};

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.image_switcher); // it could be lesson one
                                                // layout.

    mSwitcher = (ImageSwitcher) findViewById(R.id.imgswitcher);
    mSwitcher.setFactory(this);
    mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
            android.R.anim.fade_in));
    mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
            android.R.anim.fade_out));

    Gallery g = (Gallery) findViewById(R.id.gallery);
    g.setAdapter(new ImageAdapter(this));
    g.setOnItemSelectedListener(this);
    // usual onCreate stuff here, then...
    // either here or whenever you want to start the sequence
    mNext = 0;
    startNextFile();

    // Is this good !! Yes it is. count the time for all audio.
    mHandlerWholeLesson.postDelayed(mRunnableWholelesson, 25000);

}

@Override
public void onBackPressed() {
    super.onBackPressed();
    startActivity(new Intent("com.example.AmazingGame.LESSONONE"));
    System.exit(0);
    mHandlerNextfile
            .removeCallbacks(mRunnableNextFile, PlayLesson_01.class);
    mHandlerWholeLesson.removeCallbacks(mRunnableWholelesson,
            PlayLesson_01.class);

    PlayLesson_01.this.finish();
}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    // mHandlerNextFile.removeCallbacksAndMesssages(PlayLesson_01.class);
}

public void onItemSelected(AdapterView<?> parent, View v,
        final int position, long id) {

}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
    // TODO Auto-generated method stub

}

@Override
public View makeView() {
    ImageView i = new ImageView(this);
    i.setBackgroundColor(0xFF000000);
    i.setScaleType(ImageView.ScaleType.FIT_CENTER);
    i.setLayoutParams(new ImageSwitcher.LayoutParams(
            LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    return i;
}

public class ImageAdapter extends BaseAdapter {
    public ImageAdapter(Context c) {
        mContext = c;
    }

    public int getCount() {
        return mThumbIds.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView i = new ImageView(mContext);

        i.setImageResource(mThumbIds[position]);
        i.setAdjustViewBounds(true);
        i.setLayoutParams(new Gallery.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        i.setBackgroundResource(R.drawable.picture_frame);
        return i;
    }

    private Context mContext;

}

OnCompletionListener mListener = new OnCompletionListener() {

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

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

}

public void startNextFile() {

    if (mNext < myMusic.length) {

        mp = MediaPlayer.create(this, myMusic[mNext]);
        mSwitcher.setImageResource(mThumbIds[mNext++]);
        mHandlerNextfile.postDelayed(mRunnableNextFile, 3000);
    }

}

@Override
public void run() {
    // TODO Auto-generated method stub

}

}

Ответ 1

Теперь в вашем коде есть несколько неправильных вещей:

  • Если вы хотите вернуться к предыдущему действию, вы не перезапускаете его с помощью startActivity, так как поведение Android по умолчанию заключается в том, что он поддерживает стек предыдущих действий. При нажатии back он по умолчанию вернется к предыдущему действию (если только вы не запустили дочернее действие с использованием некоторых флагов.)

  • Почему вы используете System.exit(0); при обратном нажатии? Вам просто нужно вызвать finish(), чтобы завершить текущую активность.

  • Лучший способ удалить обратные вызовы из обработчика - использовать null в качестве параметра. Вы можете попробовать следующий код:

    mHandlerNextfile.removeCallbacksAndMessages(null);
    mHandlerWholeLesson.removeCallbacksAndMessages(null);
    

    так как это приведет к удалению всех обратных вызовов. Проверьте эту ссылку, чтобы узнать больше: http://developer.android.com/reference/android/os/Handler.html#removeCallbacksAndMessages(java.lang.Object)

Ответ 2

Ваш обработчик не работает, ваш медиаплеер. Просто позвоните mp.stop() в onBackPressed().

Кроме того, что сказал Арун Джордж.