Facebook登录空指针异常Android

10

我在stackoverflow上进行了大量搜索,但是没有找到解决我的问题的答案,因此我现在发帖求助。

我有一个示例Android应用程序,我正在尝试使用Facebook登录。 这里是我遵循的步骤:

环境:Android studio Android SDK版本: 22 Facebook SDK版本:4.0

我遵循了安装FB APK到模拟器的步骤,生成了开发人员哈希密钥并在应用程序->设置中更新了它。我的Android清单具有以下代码:

<uses-permission android:name="android.permission.INTERNET"/>

<activity android:name="com.facebook.FacebookActivity"
        android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
        android:theme="@android:style/Theme.Translucent.NoTitleBar" android:label="@string/app_name" />

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>

在我的activity_main.xml布局文件中,我有这段代码

<com.facebook.login.widget.LoginButton
    android:id="@+id/fblogin_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="30dp"
    android:layout_marginBottom="30dp" />

最后,在我的主 Activity 中,我有这个:

public class MainActivity extends Activity {
LoginButton loginButton;
CallbackManager callbackManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookSdk.sdkInitialize(getApplicationContext());
    callbackManager = CallbackManager.Factory.create();
    loginButton = (LoginButton) findViewById(R.id.fblogin_button);
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
        }

        @Override
        public void onCancel() {
            Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
        }

        @Override
        public void onError(FacebookException e) {
            Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
        }
    });
    setContentView(R.layout.activity_main);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("Inside Fb login","on Activiry result");
    callbackManager.onActivityResult(requestCode, resultCode, data);
}}

如下所示,我遇到了一个空指针异常

 java.lang.RuntimeException: Unable to start activity componentInfo{PROJECT.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.facebook.login.widget.LoginButton.registerCallback(com.facebook.CallbackManager, com.facebook.FacebookCallback)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
        at android.app.ActivityThread.access$800(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我在这里错过了什么?

3个回答

16

看起来您正在遇到NullPointerException,因为在调用setContentView()之前调用了findViewById(),所以当您调用loginButton.registerCallback()时,loginButton为空。

只需将对setContentView()的调用移动到顶部即可:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    FacebookSdk.sdkInitialize(getApplicationContext());

    setContentView(R.layout.activity_main); //Moved up here to resolve NPE

    callbackManager = CallbackManager.Factory.create();
    loginButton = (LoginButton) findViewById(R.id.fblogin_button);
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            Toast.makeText(getApplicationContext(),"Fb Login Success",Toast.LENGTH_LONG);
        }

        @Override
        public void onCancel() {
            Toast.makeText(getApplicationContext(),"Fb on cancel",Toast.LENGTH_LONG);
        }

        @Override
        public void onError(FacebookException e) {
            Toast.makeText(getApplicationContext(),"Fb Login Error",Toast.LENGTH_LONG);
        }
    });

}

将FacebookSdk.sdkInitialize(getApplicationContext());放在setContentView(R.layout.activity_main);之前就可以了。感谢@Daniel的帮助。 - user2752910

9

这个崩溃似乎与我们在 AndoridMenifest.xml 文件中设置的应用程序ID有关。我发现当Facebook SDK尝试创建 LoginFramment 时,应用程序ID为 null。这是 com.facebook.login.LoginFragment 类的 onCreate 方法:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(savedInstanceState != null) {
            this.loginClient = (LoginClient)savedInstanceState.getParcelable("loginClient");
            this.loginClient.setFragment(this);
        } else {
            this.loginClient = new LoginClient(this);
        }

        this.loginClient.setOnCompletedListener(new OnCompletedListener() {
            public void onCompleted(Result outcome) {
                LoginFragment.this.onLoginClientCompleted(outcome);
            }
        });
        FragmentActivity activity = this.getActivity();
        if(activity != null) {
            this.initializeCallingPackage(activity);
            if(activity.getIntent() != null) {
                //the applicationId in this.request object is null 
                this.request = (Request)activity.getIntent().getParcelableExtra("request");

            }

        }
    }

正如各个帖子中所指出的那样,由于Android未正确解析字符串资源"app_id",因此applicationId为空。您可以参考以下代码,在初始化Facebook SDK后手动设置applicationId以解决此问题。 https://github.com/jamesward/AndroidStringBug
FacebookSdk.sdkInitialize(getApplicationContext());
FacebookSdk.setApplicationId(getResources().getString(R.string.app_id));
mFacebookCallbackManager = CallbackManager.Factory.create();

为什么元数据字符串不起作用?我遇到了同样的问题...我按照你建议的做了。 - behinddwalls
我也遇到了同样的问题,现在不知道如何使用最新的SDK解决它,因为它已经弃用了sdkInitiliaze方法,因此它不允许我在onCreate中设置ApplicationId。有什么建议吗? - Emil
只需在元数据值前加上“fb”,请参见源代码:https://github.com/facebook/facebook-android-sdk/blob/sdk-version-4.8.0/facebook/src/main/java/com/facebook/FacebookSdk.java#L598 - ballzak

0

正如anj所指出的问题通常与未读取ApplicationId有关。在我的情况下,问题出在命名空间上。确保你的类的命名空间是根命名空间。因此,我的应用程序是一个Xamarin Android应用程序,我使用的命名空间如下,但我的Android应用程序的命名空间是myApp.Droid,这样strings.xml中就无法读取ApplicationId了。将命名空间更改为myApp.Droid即可解决我的问题。希望这能帮助其他遇到类似问题的人。

[assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/app_id")]
namespace myApp.Droid.Renderer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接