简体   繁体   English

在片段上按下后退按钮时强制关闭

[英]Force close when back button pressed on fragment

I have a problem in my android application. 我的Android应用程序有问题。 There is a Custome Adapter from where I am calling a fragment which have mediaPlayer to play audio file. 有一个Custome Adapter,我从那里调用一个片段,该片段具有mediaPlayer来播放音频文件。 When fragment launched, the audio file plays. 启动片段后,音频文件将播放。 If user press back button from ActionBar, no problem occurs and switched to previous fragment from where this fragment was launched. 如果用户从ActionBar按后退按钮,则不会发生任何问题,并切换到启动该片段的先前片段。 But when user again press back button, The error occurs "MyApp stop working". 但是,当用户再次按返回按钮时,将发生错误“ MyApp停止工作”。 I tried to catch the problem by breakpoint on my Main Activity's onBackPressed method, but error comes before calling this method. 我试图通过Main Activity的onBackPressed方法上的断点来捕获问题,但是在调用此方法之前会出现错误。

My Code in Custom Adapter to calling Audio Fragment: 我在自定义适配器中的代码以调用音频片段:

    android.support.v4.app.FragmentTransaction fragmentTransaction;
                    FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
                    AudioFragment fragment = new AudioFragment();
                    fragment.SoundTitle = currentAV.getFileText();
                    fragment.oneTimeOnly = 0;
                    fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.replace(R.id.fragment_container, fragment);
                    fragmentTransaction.commit();

My Code of Audio fragment having media player: 我的具有媒体播放器的音频代码片段:

public class AudioFragment extends Fragment {

private Button btnForward, btnPause, btnPlay, btnBackward;
private ImageButton btnStop;
private ImageView iv;
private MediaPlayer mediaPlayer;
private double startTime = 0;
private double finalTime = 0;
private Handler myHandler;
private int forwardTime = 90000;
private int backwardTime = 90000;
private SeekBar seekbar;
private TextView tx1,tx2,tx3, txTitle;

private boolean _isStopped = true;
private int _length = 0;

public static int oneTimeOnly = 0;
public static String SoundTitle = "";

public AudioFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view =  inflater.inflate(R.layout.fragment_audio, container, false);

    btnForward = (Button) view.findViewById(R.id.btnForward);
    btnPause = (Button) view.findViewById(R.id.btnPause);
    btnPlay = (Button)view.findViewById(R.id.btnPlay);
    btnBackward = (Button)view.findViewById(R.id.btnBackward);
    btnStop = (ImageButton)view.findViewById(R.id.btnStop);
    iv=(ImageView)view.findViewById(R.id.imageView);

    txTitle =(TextView)view.findViewById(R.id.textview);
    txTitle.setText(SoundTitle);
    tx1=(TextView)view.findViewById(R.id.textView2);
    tx2=(TextView)view.findViewById(R.id.textView3);
    tx3=(TextView)view.findViewById(R.id.textView4);
    tx3.setText("");

    myHandler = new Handler();
    seekbar=(SeekBar)view.findViewById(R.id.seekBar);

    ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
    ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);

    toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getActivity().onBackPressed();
        }
    });


    btnPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(), "Playing sound",Toast.LENGTH_SHORT).show();
            PlaySound();
        }
    });

    btnPause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(), "Pausing sound",Toast.LENGTH_SHORT).show();
            mediaPlayer.pause();
            _length = mediaPlayer.getCurrentPosition();
            btnPause.setEnabled(false);
            btnPlay.setEnabled(true);
        }
    });

    btnForward.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int temp = (int)startTime;

            if((temp+forwardTime)<=finalTime){
                startTime = startTime + forwardTime;
                mediaPlayer.seekTo((int) startTime);
                //Toast.makeText(getActivity(),"You have Jumped forward 5 seconds",Toast.LENGTH_SHORT).show();
            }
            else{
                Toast.makeText(getActivity(),"Cannot jump forward 60 seconds",Toast.LENGTH_SHORT).show();
            }
        }
    });

    btnBackward.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int temp = (int)startTime;

            if((temp-backwardTime)>0){
                startTime = startTime - backwardTime;
                mediaPlayer.seekTo((int) startTime);
                //Toast.makeText(getActivity(),"You have Jumped backward 5 seconds",Toast.LENGTH_SHORT).show();
            }
            else{
                Toast.makeText(getActivity(),"Cannot jump backward 60 seconds",Toast.LENGTH_SHORT).show();
            }
        }
    });

    btnStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            btnPause.setEnabled(false);
            btnPlay.setEnabled(true);
            _isStopped = true;
            _length = 0;
            mediaPlayer.stop();
            myHandler.removeCallbacks(UpdateSongTime);
            mediaPlayer.release();
            mediaPlayer=null;
        }
    });

    PlaySound();
    return view;
}


private Runnable UpdateSongTime = new Runnable() {
    public void run() {
        startTime = mediaPlayer.getCurrentPosition();
        tx1.setText(String.format("%d min, %d sec",

                TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
                                toMinutes((long) startTime)))
        );
        seekbar.setProgress((int)startTime);
        myHandler.postDelayed(this, 100);
    }
};


private void PlaySound(){
    if(!_isStopped){
        mediaPlayer.seekTo(_length);
        mediaPlayer.start();
        btnPause.setEnabled(true);
        btnPlay.setEnabled(false);
        return;
    }
    String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath();
    String avPath = "";
    avPath = sdpath + Gen.AudioPath;
    _isStopped = false;
    mediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(avPath));
    seekbar.setClickable(false);
    btnPause.setEnabled(false);

    mediaPlayer.start();
    finalTime = mediaPlayer.getDuration();
    startTime = mediaPlayer.getCurrentPosition();

    if (oneTimeOnly == 0) {
        seekbar.setMax((int) finalTime);
        oneTimeOnly = 1;
    }
    tx2.setText(String.format("%d min, %d sec",
            TimeUnit.MILLISECONDS.toMinutes((long) finalTime),
            TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -
                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime)))
    );

    tx1.setText(String.format("%d min, %d sec",
            TimeUnit.MILLISECONDS.toMinutes((long) startTime),
            TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
    );

    seekbar.setProgress((int)startTime);
    myHandler.postDelayed(UpdateSongTime,100);
    btnPause.setEnabled(true);
    btnPlay.setEnabled(false);
    Gen.IsMediaPlayerRun = true;
}

} }

Please help if anyone have solution. 如果有人有解决方案,请提供帮助。 Thanks 谢谢

EDIT: BELOW IS THE LOGCAT (LAST LINES) 编辑:下面是LOGCAT(最后几行)

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
  Process: com.example.khan.abc, PID: 21144
  java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference
  at com.example.khan.abc.AudioFragment$1.onClick(AudioFragment.java:125)
  at android.view.View.performClick(View.java:4848)
  at android.view.View$PerformClick.run(View.java:20262)
  at android.os.Handler.handleCallback(Handler.java:815)
  at android.os.Handler.dispatchMessage(Handler.java:104)
  at android.os.Looper.loop(Looper.java:194)
  at android.app.ActivityThread.main(ActivityThread.java:5631)
  at java.lang.reflect.Method.invoke(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

This code is producing the null pointer... 这段代码产生了空指针...

 toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
     @Override public void onClick(View v) { 
        getActivity().onBackPressed(); 
    }
 });

Add a null pointer protection 添加空指针保护

 toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
     @Override public void onClick(View v) { 
        Activity parent = getActivity();
        if(parent != null)
            parent.onBackPressed(); 
    }
 });

However, your code is a little bit strange ... 但是,您的代码有点奇怪...

For example: you create the fragment and set the clickListener for toolbar. 例如:您创建片段并为工具栏设置clickListener。 Then, you return to previous fragment.. however, your tool bar is still referencing the listener from killed fragment... 然后,您返回到上一个片段。.但是,您的工具栏仍在从被杀死的片段中引用侦听器...

I think the best way is handle the tool bar in parent activity... I'm not sure if is possible for you.. but I'd change that... 我认为最好的方法是处理家长活动中的工具栏...我不确定您是否可以..但我会改变这一点...

Hope this could help. 希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM