Swiping to previous fragment restarts app

Hello

After adding the view pager and FragmentStatePagerAdapter (from Chapter 11: Using ViewPagers), the new CrimePagerActivity does start and I can swipe forward normally, but if I try to swipe to the Crime where I came from, the app freezes for a second then restarts the app back to the list view.

For example, if I start at Crime 3, I can move forward to 4 (or backwards to 2), but if I move back to 3, it will freeze and crash.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Stack trace of error:
11-02 13:23:23.906 4592-4592/com.bignerdranch.android.criminalintent E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bignerdranch.android.criminalintent, PID: 4592
java.lang.StackOverflowError: stack size 8MB
at com.bignerdranch.android.criminalintent.CrimeFragment$1.beforeTextChanged(CrimeFragment.java:0)
at android.widget.TextView.sendBeforeTextChanged(TextView.java:8268)
at android.widget.TextView.setText(TextView.java:4356)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(CrimeFragment.java:67)
at android.widget.TextView.sendOnTextChanged(TextView.java:8318)
at android.widget.TextView.setText(TextView.java:4459)
at android.widget.TextView.setText(TextView.java:4313)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4288)
at com.bignerdranch.android.criminalintent.CrimeFragment$1.onTextChanged(C
11-02 13:23:23.998 4592-4592/com.bignerdranch.android.criminalintent E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 1896744)
11-02 13:23:24.007 4592-4592/com.bignerdranch.android.criminalintent E/AndroidRuntime: Error reporting crash
android.os.TransactionTooLargeException: data parcel size 1896744 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:505)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4427)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:90)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Also, I noticed in the solutions file that Big Nerd Ranch does not have the static newInstance method in CrimeFragment.java for chapter 11.

Please assist.

Interesting error. I haven’t encountered this myself, but a StackOverflow error is usually the result of a bad recursive call. The error shows logs of onTextChanged method in CrimeFragment and once a call to beforeTextChanged on a strange 0 line. It could be the cause of a recursive call.
Could you maybe show your implementation of the new TextWatcher interface in the addTextChangedListener?

I was thinking along similar lines, since when monitoring the memory when running the app, the memory quickly drops to 0% before restarting the app in the launcher activity.
Please see below:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_crime, container, false);
mTitleField = (EditText) v.findViewById(R.id.crime_title);
mTitleField.setText(mCrime.getTitle());
mTitleField.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            //Intentionally left blank
        }

        @Override
        public void onTextChanged(CharSequence s, int i, int i1, int i2) {
            mTitleField.setText(s.toString());
        }

        @Override
        public void afterTextChanged(Editable editable) {
            //Intentionally left blank
        }
    });// END OF adding TextChangeListener to mTitleField

The problem is a sneaky one, and not immideatly noticable if you aren’t aware what’s causing it.
The Error log actually shows what’s causing the problem as well. The recursion happens inside the onTextChanged method. (You can see this by the amount of times the same method is called inside the error log. onTextChanged kept being called and causing an error. This endless loop eventually filled up the whole stack and caused an overflow.)

In this method you are calling the setText of the mTitleField.
@Override
public void onTextChanged(CharSequence s, int i, int i1, int i2) {
mTitleField.setText(s.toString());
}

The problem this causes is a recursion of the same onTextChanged method, cause the Text on the mTitleField did change due to the setText method you called.
The thing you want to do here is changing the title of the model (the Crime), instead of what’s on the screen. The title of the model will reflect what’s on screen eventually. So instead of calling setText on mTitleField, you want to call setTitle on the mCrime object :slight_smile:

Here’s my code for the same overriden method:
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
mCrime.setTitle(charSequence.toString());
}

Hope this solves your problem! If not, than I’m hugely mistaken hehe. If it did, I hope I managed to clear the confusion behind the error :slight_smile:

Excellent! Yes you are correct. Thank you very much.

Glad to hear that it solved the problem! Wish you much enjoyment while working through the rest of the book :slight_smile: