谁能告诉我为什么后退按钮会导致应用程序崩溃?无论我在代码中更改什么,无论是 try/catch、onDestroy、onBackPressed,它每次都会崩溃,但前提是我启动了一次媒体播放器。如果我没有从屏幕上启动它,后退按钮不会使应用程序崩溃。我究竟做错了什么?谢谢
public class Lesson1Grammar extends Activity implements SeekBar.OnSeekBarChangeListener{
private SeekBar seekBar;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
MediaPlayer wholeTextPlayer;
private Utilities utils;
final Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lesson1grammar);
final RelativeLayout playerScreen = (RelativeLayout) findViewById(R.id.playerScreen);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
utils = new Utilities();
final ImageButton btn_player_screen = (ImageButton) findViewById(R.id.btn_player_screen);
btn_player_screen.setOnClickListener(new View.OnClickListener() {
//this hides/unhides the part of the layout in which the player is
@Override
public void onClick(View arg0) {
if (playerScreen.isShown()) {
playerScreen.setVisibility(View.GONE);
} else {
playerScreen.setVisibility(View.VISIBLE);
}
}
});
final Button btn_default_acc_whole = (Button) findViewById(R.id.btn_default_acc_whole);
btn_default_acc_whole.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {//problem here is
if (playerState == PlayerState_ScAcc) {
stopSentencePlayer();
setEngAu(R.raw.default_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_DefAcc);
}else if (playerState == PlayerState_Sc_Paused){
stopSentencePlayer();
setEngAu(R.raw.default_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_DefAcc);
}else if (playerState == PlayerState_DefAcc) {
wholeTextPlayer.pause();
setPlayerState(PlayerState_Def_Paused);
} else if (playerState == PlayerState_Def_Paused) {
wholeTextPlayer.start();
setPlayerState(PlayerState_DefAcc);
} else {
setEngAu(R.raw.default_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_DefAcc);
}
}
});
final Button btn_scottish_acc_whole = (Button) findViewById(R.id.btn_scottish_acc_whole);
btn_scottish_acc_whole.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {//problem here is
if (playerState == PlayerState_DefAcc) {
stopSentencePlayer();
setEngAu(R.raw.scottish_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_ScAcc);
}else if (playerState == PlayerState_Def_Paused){
stopSentencePlayer();
setEngAu(R.raw.scottish_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_ScAcc);
}else
if (playerState == PlayerState_ScAcc) {
wholeTextPlayer.pause();
setPlayerState(PlayerState_Sc_Paused);
} else if (playerState == PlayerState_Sc_Paused) {
wholeTextPlayer.start();
setPlayerState(PlayerState_ScAcc);
} else {
setEngAu(R.raw.scottish_acc_audio);
wholeTextPlayer.start();
setPlayerState(PlayerState_ScAcc);
}
}
});
}
private final int PlayerState_Def_Paused = 1;
private final int PlayerState_Sc_Paused = 2;
private final int PlayerState_DefAcc = 3;
private final int PlayerState_ScAcc = 4;
private int playerState;
private void setPlayerState(int state) {
playerState = state;
}
public void setEngAu(int engAu) {
wholeTextPlayer = MediaPlayer.create(this, engAu);
seekBar.setProgress(0);
seekBar.setMax(100);
updateSeekBar();
}
public void updateSeekBar() {
handler.postDelayed(mUpdateTimeTask, 100);
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = wholeTextPlayer.getDuration();
long currentDuration = wholeTextPlayer.getCurrentPosition();
songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));
int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
seekBar.setProgress(progress);
handler.postDelayed(this, 100);
}
};
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
}
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
int totalDuration = wholeTextPlayer.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
wholeTextPlayer.seekTo(currentPosition);
updateSeekBar();
}
private void stopSentencePlayer() {
if(wholeTextPlayer !=null){
try{
wholeTextPlayer.release();
}catch(Exception e){
e.printStackTrace();
}
}
}
@Override
public void onBackPressed(){
if(wholeTextPlayer != null){
wholeTextPlayer.release();
}
finish();
super.onBackPressed();
}
}
另一种选择可能是返回到启动媒体播放器的相同屏幕状态,在这种情况下音频可能会暂停等,但这似乎超出了我的能力:(播放器可以在后台播放,没关系。
我希望我捕获了正确的部分。我只是一个新手:)
1-06 17:27:02.909 6596-6596/com.tanuljangolulmenetkozben.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException
at android.media.MediaPlayer.getDuration(Native Method)
at com.tanuljangolulmenetkozben.app.Lesson1Grammar$4.run(Lesson1Grammar.java:128)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3705)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
11-06 17:27:06.022 1675-1835/? E/Omap4ALSA﹕ called drain&close'
最佳答案
正如我评论的那样,当用户点击 onBackPressed()
时,Handler
继续运行,而您的 Activity
正在破坏。因此,您必须检查此处理程序是否正在运行并停止它,就像您在 onStopTrackingTouch()
方法中所做的那样:
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
...
}
所以,onBackPressed
应该是这样的:
@Override
public void onBackPressed() {
if (wholeTextPlayer != null) {
wholeTextPlayer.release();
if (handler != null)
handler.removeCallbacks(null);
}
finish();
super.onBackPressed();
}
另一个好的行为应该是在 onPause
或 onStop
中停止它:
@Override
protected void onStop() {
super.onStop();
if (handler != null)
handler.removeCallbacks(null);
}
关于android - Mediaplayer 使应用程序崩溃 onBackPressed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33562287/