我有一个简单的活动,使用Facebook按钮来使用登录(使用Facebook Android SDK:
package com.example.adminn.facebooktest;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.content.Intent;
import android.view.View;
import android.app.Activity;
import android.support.v4.app.FragmentActivity;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.CallbackManager;
import com.facebook.login.LoginManager;
import com.facebook.login.widget.LoginButton;
import com.facebook.login.LoginResult;
import com.facebook.FacebookCallback;
import java.util.Arrays;
public class MainActivity extends FragmentActivity {
CallbackManager callbackManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this.getApplicationContext());
setContentView(R.layout.activity_main);
callbackManager = CallbackManager.Factory.create();
//LoginButton loginButton = (LoginButton) findViewById(R.id.login_button);
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
//Toast toast = Toast.makeText(MainActivity.this, "OnSuccess:" + loginResult.getAccessToken().toString(), Toast.LENGTH_LONG);
//toast.show();
}
@Override
public void onCancel() {
Toast toast = Toast.makeText(MainActivity.this, "Cancel!!", Toast.LENGTH_LONG);
toast.show();
}
@Override
public void onError(FacebookException e) {
Toast toast = Toast.makeText(MainActivity.this, "Error!", Toast.LENGTH_LONG);
toast.show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode,final Intent data){
super.onActivityResult(requestCode,resultCode,data);
callbackManager.onActivityResult(requestCode,resultCode,data);
}
public void facebookLogin(View v){
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile","user_friends"));
}
}
按下按钮后,上面的代码崩溃,出现以下错误:
Process: com.example.adminn.facebooktest, PID: 8830
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=64206, result=-1, data=Intent { (has extras) }} to activity {com.example.adminn.facebooktest/com.example.adminn.facebooktest.MainActivity}: java.lang.NullPointerException: Argument 'context' cannot be null
at android.app.ActivityThread.deliverResults(ActivityThread.java:3626)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3669)
at android.app.ActivityThread.access$1300(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
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:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
Caused by: java.lang.NullPointerException: Argument 'context' cannot be null
at com.facebook.internal.Validate.notNull(Validate.java:67)
at com.facebook.appevents.AppEventsLogger.<init>(AppEventsLogger.java:652)
at com.facebook.appevents.AppEventsLogger.newLogger(AppEventsLogger.java:417)
at com.facebook.login.LoginLogger.<init>(LoginLogger.java:67)
at com.facebook.login.LoginManager.getLogger(LoginManager.java:397)
at com.facebook.login.LoginManager.logCompleteLogin(LoginManager.java:415)
at com.facebook.login.LoginManager.onActivityResult(LoginManager.java:190)
at com.facebook.login.LoginManager$1.onActivityResult(LoginManager.java:140)
at com.facebook.internal.CallbackManagerImpl.onActivityResult(CallbackManagerImpl.java:82)
at com.example.adminn.facebooktest.MainActivity.onActivityResult(MainActivity.java:88)
at android.app.Activity.dispatchActivityResult(Activity.java:6161)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3622)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3669)
at android.app.ActivityThread.access$1300(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
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:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
我已经使用断点对SDK的源代码进行了一些挖掘,并且我意识到onActivityResult被调用了两次(当我按下按钮而另一个没有理由时)。它第一次顺利并检索令牌和会话信息。完成后,LoginManager.java中的上下文字段将设置为null。由于callbackManager.onActivityResult在某些时候调用了logCompleteLogin,而logCompleteLogin又根据空的上下文创建了一个LoginLogger,因此应用程序崩溃了。
为什么onActivityResult被调用两次?据我所知,除了MainActivity之外,还有另一项活动,即FacebookActivity。
答案 0 :(得分:3)
这两个问题都已解决,而且它们是相关的。
发生了什么,我无法理解的是,facebook按钮有一个触发登录过程的基础事件。我在MainActivity上设置了另一个事件来执行click。因此,在内部,发生的事情是,facebookactivity正在创建两次,导致两次调用onActivityResult。对onActivityResult的第一次调用使LoginManager的内部状态保留了一个空的上下文字段(以前是MainActivity)。第二个调用假定上下文不为null,如果它是崩溃应用程序(内部有Validate验证)。
回退到以前版本的SDK,因为在调用logInWithReadPermissions时,LogginManager.context没有被取消,导致第二个调用“有效”。
答案 1 :(得分:2)