Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Ribbit app force closes after Signup

For some reason, when a user first signs up and is directed back to MainActivity my app force closes. And then every time I try to open the app after that it immediately force closes. I have debugged and found the offending code, but I can't figure out what is causing it.

    package com.davidwestberry.ribbit.ui;

    import android.app.AlertDialog;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.util.Log;
    import android.view.ContextMenu;
    import android.view.LayoutInflater;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.GridView;
    import android.widget.TextView;

    import com.davidwestberry.ribbit.R;
    import com.davidwestberry.ribbit.adapters.UserAdapter;
    import com.davidwestberry.ribbit.utils.ParseConstants;
    import com.parse.FindCallback;
    import com.parse.ParseException;
    import com.parse.ParseQuery;
    import com.parse.ParseRelation;
    import com.parse.ParseUser;
    import com.parse.SaveCallback;

    import java.util.List;

    public class FriendsFragment extends Fragment {

        private static final String TAG =     FriendsFragment.class.getSimpleName();

        protected List<ParseUser> mFriends;
        protected ParseRelation<ParseUser> mFriendsRelation;
        protected ParseUser mCurrentUser;
        protected GridView mGridView;

        /**
         * Mandatory empty constructor for the fragment manager to     instantiate the
         * fragment (e.g. upon screen orientation changes).
         */
        public FriendsFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
            View rootview = inflater.inflate(R.layout.fragment_friends_grid, container, false);

            mGridView = (GridView) rootview.findViewById(R.id.friendsGrid);

            TextView emptyTextView = (TextView) rootview.findViewById(android.R.id.empty);
            mGridView.setEmptyView(emptyTextView);

            registerForContextMenu(rootview);

            return rootview;
        }

        @Override
        public void onResume() {
            super.onResume();

            mCurrentUser = ParseUser.getCurrentUser();
            mFriendsRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
            if (!mCurrentUser.isNew()) {
                getFriendsList();
            }
            /**
             * This interface must be implemented by activities that contain     this
             * fragment to allow an interaction in this fragment to be     communicated
             * to the activity and potentially other fragments contained in that
             * activity.
             * <p/>
             * See the Android Training lesson <a href=
             *     "http://developer.android.com/training/basics/fragments/communicatin    g.html"
             * >Communicating with Other Fragments</a> for more information.
             */
        }

        private void getFriendsList() {
            ParseQuery<ParseUser> query = mFriendsRelation.getQuery();
            query.addAscendingOrder(ParseConstants.KEY_USERNAME);
            query.findInBackground(new FindCallback<ParseUser>() {
                @Override
                public void done(List<ParseUser> friends, ParseException e) {
                    mFriends = friends;

                    int i = 0;
                    if (e == null) {
                        String[] usernames = new String[mFriends.size()];
                        for (ParseUser user : mFriends) {
                            usernames[i] = user.getUsername();
                            i++;
                        }
                        if (mGridView.getAdapter() == null) {
                            UserAdapter adapter = new UserAdapter(getActivity(),    mFriends);
                            mGridView.setAdapter(adapter);
                        }
                        else{
                             ((UserAdapter)mGridView.getAdapter()).refill(mFriends);
                        }
                    } else {
                        Log.e(TAG, e.getMessage());
                        Log.i(TAG, "Username: " + mCurrentUser.getUsername());
                        Log.i(TAG, "Authenticated: " +  mCurrentUser.isAuthenticated());
                        Log.i(TAG, "Data Available: " +    mCurrentUser.isDataAvailable());
                    }
                }
            });
        }

        private void ErrorAlert(String title, String message) {
            AlertDialog.Builder builder = new     AlertDialog.Builder(getActivity());
            builder.setMessage(message)
                    .setTitle(title)
                    .setPositiveButton(android.R.string.ok, null);
            AlertDialog dialog = builder.create();
            dialog.show();
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,   ContextMenu.ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);

            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
            menu.setHeaderTitle(mFriends.get(info.position).getUsername());
            MenuInflater inflater = getActivity().getMenuInflater();
            inflater.inflate(R.menu.menu_friends_list, menu);
        }

        @Override
        public boolean onContextItemSelected(MenuItem item) {
            AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
            int selectId = item.getItemId();
            int selectPosition = menuInfo.position;
            if (selectId == R.id.action_remove) {
                Log.i(TAG, mFriends.get(selectPosition).getUsername());
                mFriendsRelation.remove(mFriends.get(selectPosition));
                mCurrentUser.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        if (e != null) {
                            Log.e(TAG, e.getMessage());
                        }
                    }
                });
            }
            getFriendsList();
            return super.onContextItemSelected(item);
        }
    }

I actually fixed the force close problem by moving the line String[] usernames = new String[mFriends.size()]; into the if statement where it is now, it didn't fix the problem, it just handles the error. In the videos that line was outside of the if statement just under mFriends = friends;. The error is that the variable friends is null at this point, but only if the user has just completed the signup process. The error actually happens at the query. java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject. The full source code is on github