Search code examples
androidnullpointerexceptionfacebook-loginfragmentmanagerfacebook-sdk-3.1

NullPointerException getSupportFragmentManager() with Facebook onSessionStateChange


I am using the Facebook SDK to do a FB login. Sometimes I receive a random NullPointerException when returning from the Facebook login.

The NPE is on my line:

FragmentManager fm = getActivity().getSupportFragmentManager();

My FB login is in a single Fragment. When the user logs into FB and is successful, it changes the Fragment to another. Why am I getting this NPE?

private void onSessionStateChange(Session session, SessionState state, Exception exception) {
    if (state.isOpened()) { 
        Log.i("Facebook", "Logged In");
        mPrefs.setFbLoggedIn(true);

        Request.newMeRequest(session, new Request.GraphUserCallback() {
            @Override
            public void onCompleted(GraphUser user, Response response) {
                if (response.getError() == null) {
                    FragmentManager fm = getActivity().getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    ft.setCustomAnimations(R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left, 
                            R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
                    ft.remove(fm.findFragmentById(R.id.container));
                    ft.add(R.id.container, LoadingFragment.newInstance(), "loadingFragment");
                    ft.commit();

                    String fbId = "";
                    try { fbId = user.getId(); }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    String fullName = "";
                    try { fullName = user.getName(); }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    String email = "";
                    try { email = user.getProperty("email").toString(); }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    String gender = "";
                    try { gender = user.getProperty("gender").toString(); }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    String pictureUrl = "";
                    try { pictureUrl = "http://graph.facebook.com/" + user.getId() + "/picture?type=large"; }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    String birthdate = "";
                    try {
                        if (user.getBirthday() != null && !user.getBirthday().isEmpty()) {
                            try { 
                                DateTime dateTime = DateTime.parse(user.getBirthday(), DateTimeFormat.forPattern("MM/dd/yyyy"));
                                DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ")
                                        .withZone(DateTimeZone.getDefault());
                                birthdate = formatter.print(dateTime);
                            } 
                            catch (IllegalArgumentException e) { e.printStackTrace(); }
                        }
                    }
                    catch (NullPointerException e) { e.printStackTrace(); }

                    User u = new User(fbId, email, fullName, gender, birthdate, pictureUrl);
                    FacebookMethods.writeFbInfo(getActivity(), u);

                    ((MainActivity)getActivity()).connectToServer();
                }
                else {
                    Toast.makeText(getActivity(), response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        }).executeAsync();
    } 
    else if (state.isClosed()) { 
        Log.i("Facebook", "Logged Out"); 
        mPrefs.setFbLoggedIn(false);
    }
}

Stacktrace (not full, but the important lines)

java.lang.NullPointerException
   at com.walintukai.lfdate.LoginFragment$2.onCompleted(LoginFragment.java:278)
   at com.facebook.Request$1.onCompleted(Request.java:303)
   at com.facebook.Request$4.run(Request.java:1726)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:136)
   at android.app.ActivityThread.main(ActivityThread.java:5050)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
   at dalvik.system.NativeStart.main(NativeStart.java)

Solution

  • The getActivity() here can return null if the Activity was stopped (back button, home, recent, ...).

    To avoid error simply stop the method early:

       Request.newMeRequest(session, new Request.GraphUserCallback() {
            @Override
            public void onCompleted(GraphUser user, Response response) {
                if (getActivity() == null) {
                    // The activity was stopped
                    return;
                }
                // else we can continue 
                // ...
            }
        });