Android Facebook Login SDK:getActivity().getCallingActivity()返回空崩溃排查
What's Happening
You're running into a null pointer exception while implementing Facebook Login with version 4.0.0 of the Facebook Android SDK. Firebase Crashlytics is catching this crash on specific devices, but you can’t reproduce it on your test hardware. The crash occurs because getActivity().getCallingActivity() returns null, and the SDK tries to call getPackageName() on that null value.
Your Environment & Crash Breakdown
- Facebook SDK Dependency:
implementation ('com.facebook.android:facebook-android-sdk:4.0.0'){ exclude group: 'com.android.support' } - Affected Devices:
- Unrooted Galaxy S7 (Android 7.0)
- Unrooted Huawei Honor 9(STF-L09) (Android 8.0)
- Crash Location: The issue hits in the Facebook SDK's
LoginFragment.javaat line 68, within theonCreatemethod:@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { loginClient = savedInstanceState.getParcelable(SAVED_LOGIN_CLIENT); loginClient.setFragment(this); } else { loginClient = new LoginClient(this); } callingPackage = getActivity().getCallingActivity().getPackageName(); // Crash here request = (LoginClient.Request) getActivity().getIntent().getParcelableExtra(EXTRA_REQUEST); loginClient.setOnCompletedListener(new LoginClient.OnCompletedListener() { @Override public void onCompleted(LoginClient.Result outcome) { onLoginClientCompleted(outcome); } }); } - Why This Happens: The
getCallingActivity()method from Android'sActivityclass can return null in specific scenarios—like when the activity wasn’t launched viastartActivityForResult, or if the calling app's process was terminated before the login fragment loads. Here's the source code for that method:public ComponentName getCallingActivity() { try { return ActivityManager.getService().getCallingActivity(mToken); } catch (RemoteException e) { return null; } }
How to Fix This Crash
1. Upgrade to a Newer Facebook SDK Version
First off, SDK 4.0.0 is extremely outdated (released back in 2015). Facebook has almost certainly patched this null pointer bug in later versions of the SDK. Upgrading to a more recent stable 4.x release (like 4.40.0, the last of the 4.x line) or migrating to the newer 12.x+ SDK will likely resolve the issue outright. For example, update your dependency to:
implementation 'com.facebook.android:facebook-android-sdk:4.40.0'
Note: If you move to a newer SDK version, you may need to adjust your login code to match updated APIs—like using LoginManager instead of LoginFragment if that's the recommended flow now.
2. Workaround for the Outdated SDK (If You Can't Upgrade)
If upgrading isn’t feasible right now, you can create a custom subclass of LoginFragment to handle the null case manually:
public class SafeLoginFragment extends LoginFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Activity activity = getActivity(); if (activity != null) { ComponentName callingActivity = activity.getCallingActivity(); try { // Use reflection to access the private callingPackage field Field callingPackageField = LoginFragment.class.getDeclaredField("callingPackage"); callingPackageField.setAccessible(true); if (callingActivity != null) { callingPackageField.set(this, callingActivity.getPackageName()); } else { // Fallback to your app's package name as a safe default Log.w("SafeLoginFragment", "Calling activity is null—using app package as fallback"); callingPackageField.set(this, activity.getPackageName()); } } catch (NoSuchFieldException | IllegalAccessException e) { // Log the error instead of crashing the app Log.e("SafeLoginFragment", "Failed to set callingPackage", e); } } } }
Then replace all uses of the default LoginFragment with your SafeLoginFragment in your app's layout files or code.
3. Double-Check Your Login Flow
Make sure you’re launching the Facebook login flow correctly. For older SDK versions, this typically means using startActivityForResult to launch the login activity/fragment. If you’re starting the fragment directly without a proper calling context, that could trigger the null getCallingActivity() scenario.
Final Tips
Since you can’t reproduce this on your test devices, after applying a fix, keep an eye on Crashlytics to confirm the crash stops appearing. You can also try simulating the issue by killing your app's process before the login fragment loads to verify your fix works in that edge case.
内容的提问来源于stack exchange,提问作者Carlos Cabello Ruiz

