简体   繁体   中英

I'm using Fragments and when I press the back button really fast the app crashes. It happens randomly

I'm using Fragments and when I press the back button really fast the android app crashes. It happens randomly, here is the java code:

public class PlayerFragment extends Fragment {
    List<County> feeds;
    String action = "counties";
    private static MediaPlayer mMediaPlayer;

    TextView descr;
    TextView feed_id;
    TextView status;
    TextView listeners;
    TextView genre;
    TextView bitrate;

    private static Button switchButton;

    private AdView mAdView;
    InterstitialAd mInterstitialAd;

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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_player, container, false);
        //view called and initialized
        initView(rootView);
        updateView();
        AdRequest adRequest = new AdRequest.Builder()
                .build();
        mAdView.loadAd(adRequest);

        // set the ad unit ID
        mInterstitialAd.setAdUnitId(getString(R.string.interstitial_full_screen));

        // Load ads into Interstitial Ads
        mInterstitialAd.loadAd(adRequest);

        mInterstitialAd.setAdListener(new AdListener() {
            public void onAdLoaded() {
                showInterstitial();
            }
        });

        final Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(RadioApiClient.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create());
        Retrofit retrofit = builder.build();

        RadioApiClient client = retrofit.create(RadioApiClient.class);

        Call<Counties> call = client.getCounties(action,
                BrowseStateFragment.stateId,
                RadioApiClient.JSON_RESPONSE,
                RadioApiClient.API_KEY);
        Log.d("Accessing url", client.getCounties(action, BrowseStateFragment.stateId,
                RadioApiClient.JSON_RESPONSE,
                RadioApiClient.API_KEY).request().url().toString());
        call.enqueue(new Callback<Counties>() {

            @Override
            public void onResponse(Call<Counties> call, Response<Counties> response) {


                feeds = response.body().getCounties();

                AudioManager amanager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
                int maxVolume = amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
                amanager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume, 0);
                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        togglePlayPause();
                    }
                });

                String station = BrowseFeedsFragment.station;
                Toast.makeText(getActivity(), "Setting radio", Toast.LENGTH_LONG).show();
                if (mMediaPlayer.isPlaying()) {
                    mMediaPlayer.stop();
                    Toast.makeText(getActivity(), "stopping radio", Toast.LENGTH_LONG).show();

                    mMediaPlayer.reset();
                    Toast.makeText(getActivity(), "resetting radio", Toast.LENGTH_LONG).show();
                }
                try {
                    Toast.makeText(getActivity(), "Trying to play ", Toast.LENGTH_LONG).show();
                    mMediaPlayer.setDataSource(station);
                    mMediaPlayer.prepareAsync();
                    mMediaPlayer.start();
                    showInterstitial();
                    Toast.makeText(getActivity(), "playing", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onFailure(Call<Counties> call, Throwable t) {
                Log.d("no success", "" + "onfailure");
                t.printStackTrace();
            }
        });
        // Inflate the layout for this fragment
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public void onPause() {
        if (mAdView != null) {
            mAdView.pause();
        }
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mAdView != null) {
            mAdView.resume();
            showInterstitial();
        }
    }

    @Override
    public void onDestroy() {
        if (mAdView != null) {
            mAdView.destroy();
        }
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    private void togglePlayPause() {
        if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.pause();
            switchButton.setText("Play");
            Toast.makeText(getActivity(), "Paused", Toast.LENGTH_LONG).show();

        } else {
            mMediaPlayer.start();
            switchButton.setText("Pause");


            Toast.makeText(getActivity(), "Playing", Toast.LENGTH_LONG).show();

        }
    }

    private void showInterstitial() {
        if (mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
        }
    }

    public void initView(View rootView) {
        descr = (TextView) rootView.findViewById(R.id.descr);
        feed_id = (TextView) rootView.findViewById(R.id.feed_id);
        status = (TextView) rootView.findViewById(R.id.status);
        listeners = (TextView) rootView.findViewById(R.id.listeners);
        genre = (TextView) rootView.findViewById(R.id.genre);
        bitrate = (TextView) rootView.findViewById(R.id.bitrate);
        switchButton = (Button) rootView.findViewById(R.id.switchButton);
        mAdView = (AdView) rootView.findViewById(R.id.adView);
        mInterstitialAd = new InterstitialAd(getActivity());

    }

    public void updateView() {
        //update views

        descr.setText("Description: " + BrowseFeedsFragment.descr);
        feed_id.setText("Feed Id: " + BrowseFeedsFragment.feed_id);

        if (BrowseFeedsFragment.status == "1") {
            status.setText("Status: " + "Live Streaming Active");
        } else {
            status.setText("Status: " + "Live Streaming Offline");
        }

        listeners.setText("Listerners: " + BrowseFeedsFragment.listeners);
        genre.setText("Genre: " + BrowseFeedsFragment.genre);
        bitrate.setText("Bitrate: " + BrowseFeedsFragment.bitrate + "KBPS");

        Log.d("Success", "" + "Update Success");

        //event handling
        switchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                togglePlayPause();
            }
        });

    }
}

An the error message that I am getting is this one:

> FATAL EXCEPTION: main
>     Process: com.kwawannan.policedispatchlivescanner, PID: 27704
>     java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null
> object reference
>          at android.widget.Toast.<init>(Toast.java:103)
>          at android.widget.Toast.makeText(Toast.java:256)
>          at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.togglePlayPause(PlayerFragment.java:208)
>          at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.access$200(PlayerFragment.java:36)
>          at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment$2$1.onPrepared(PlayerFragment.java:123)
>          at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2872)
>          at android.os.Handler.dispatchMessage(Handler.java:102)
>          at android.os.Looper.loop(Looper.java:154)
>          at android.app.ActivityThread.main(ActivityThread.java:6119)
>          at java.lang.reflect.Method.invoke(Native Method)
>          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
>          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

It happens because onResponse is called after fragment is destroyed and detached from activity.

Proper solution for that is to cancel or dispose call when fragment is being destroyed:

call call.cancel() or call.dispose method in onDestroyView

As showing error code.

com.kwawannan.policedispatchlivescanner, PID: 27704 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference at android.widget.Toast.(Toast.java:103)

You should use getContext() instead of getActivity(); like

Toast.makeText(getContext(), "msg text", Toast.LENGTH_LONG).show();

Change your toggle method like this one below:

private void togglePlayPause() {
        Activity activity = getActivity();
        if (mMediaPlayer!=null && activity!=null) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
                switchButton.setText("Play");
                Toast.makeText(activity, "Paused", Toast.LENGTH_LONG).show();    
            } else {
                mMediaPlayer.start();
                switchButton.setText("Pause");
                Toast.makeText(activity, "Playing", Toast.LENGTH_LONG).show();
            }
        }
    }

I hope this will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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