我有一种方法可以在Facebook上调用用户的个人资料信息。其中一个参数是Context
。我从Activity's context
传递Fragment
,但我的一些用户获得了NullPointerException
上下文。
我正在Activity
的{{1}}方法中保存onAttach
的引用。为什么这会给我一个Fragment
?
问题在于这个方法:
NPE
此回调已完成fbLoginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Log.i("Facebook", "Logged In");
addLoadingFragment();
FacebookHelper.requestUserInfo(mActivity, loginResult.getAccessToken(), new Runnable() {
@Override
public void run() {
if (mEnteredCode != null) {
Log.i(TAG, "Logging in with entered activation code");
new VolleyHelper(mActivity).mLogin(mEnteredCode);
}
else {
Log.i(TAG, "Logging in with existing account");
new VolleyHelper(mActivity).mLogin(null);
}
}
});
}
@Override
public void onCancel() {
Log.i("Facebook", "Login Cancelled");
}
@Override
public void onError(FacebookException e) {
Log.i("Facebook", "Error: " + e.getLocalizedMessage());
ViewHelper.showCustomToast(getActivity(), e.getLocalizedMessage(), null);
addLoginFragment();
}
});
,我正在asynchronously
内嵌入此异步调用。我怀疑这个问题与此有关。任何人都可以解释为什么这是一个问题?
堆栈跟踪
Runnable
此方法在我的Facebook帮助程序类中,它请求您的FB信息并将信息保存到SharedPreferences。 runnable作为参数传入,因为此方法用于其他地方。
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
at com.walintukai.lovelup.utils.SharedPrefs.<init>(SharedPrefs.java:60)
at com.walintukai.lovelup.utils.VolleyHelper.<init>(VolleyHelper.java:42)
at com.walintukai.lovelup.fragments.LoginFragment$1$1.run(LoginFragment.java:209)
at com.walintukai.lovelup.utils.FacebookHelper$1.onCompleted(FacebookHelper.java:129)
at com.facebook.GraphRequest$1.onCompleted(GraphRequest.java:295)
at com.facebook.GraphRequest$5.run(GraphRequest.java:1243)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
这是在上面调用Facebook帮助方法的片段。
public static void requestUserInfo(final Context context, final AccessToken accessToken, final Runnable runnable) {
GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
String id = "";
String name = "";
String email = "";
String gender = "";
String birthdate = "";
String pictureUrl = "";
int timezone = 0;
if (jsonObject != null) {
try {
Log.i(TAG, "FB User: " + jsonObject.toString());
if (jsonObject.has("id")) {
id = jsonObject.getString("id");
pictureUrl = "https://graph.facebook.com/" + id + "/picture";
}
if (jsonObject.has("name")) {
name = jsonObject.getString("name");
}
if (jsonObject.has("email")) {
email = jsonObject.getString("email");
}
if (email.isEmpty()) {
email = id + "@facebook.com";
}
if (jsonObject.has("gender")) {
gender = jsonObject.getString("gender");
}
if (jsonObject.has("birthday")) {
String fbBirthday = jsonObject.getString("birthday");
try {
LocalDate localDate = LocalDate.parse(fbBirthday,
DateTimeFormat.forPattern("MM/dd/yyyy"));
LocalTime localTime = new LocalTime(0, 0, 0);
DateTime dateTime = localDate.toDateTime(localTime, DateTimeZone.UTC);
DateTimeFormatter formatter = ISODateTimeFormat.dateTime()
.withZone(DateTimeZone.UTC);
birthdate = formatter.print(dateTime);
}
catch (IllegalArgumentException e) { e.printStackTrace(); }
}
if (jsonObject.has("timezone")) {
timezone = jsonObject.getInt("timezone");
}
}
catch (JSONException e) { e.printStackTrace(); }
SharedPrefs prefs = new SharedPrefs(context);
prefs.setFbAccessToken(accessToken.getToken());
prefs.setFbId(id);
prefs.setFbFullName(name);
prefs.setFbEmail(email);
prefs.setFbGender(gender);
prefs.setFbBirthdate(birthdate);
prefs.setFbPictureUrl(pictureUrl);
prefs.setFbTimezone(timezone);
// Execute passed in runnable
runnable.run();
}
}
});
request.executeAsync();
}
}
答案 0 :(得分:0)
由于回调是异步的,因此用户可能已退出片段,并且参考mActivity现在指向null。在任何异步请求中,请确保检查mActivity!= null,这样可以防止出现这种情况。
如果您想要保留数据,即使片段或活动可能已关闭,请在注册请求时创建SharedPreference对象:
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mActivity);