onActivityResult 调用了两次
onActivityResult called twice
我有一个简单的 activity,带有一个用于登录的 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.access00(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.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.access00(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 中的上下文字段将设置为空。由于 callbackManager.onActivityResult 在某些时候调用了 logCompleteLogin,后者又根据空上下文创建了一个 LoginLogger,因此应用程序崩溃了。
为什么 onActivityResult 被调用了两次?据我所知,除了MainActivity,还有一个activity,就是FacebookActivity。
在 Facebook android SDK 的最新 v4.2.0 中,您看到的 NPE 看起来是 this 提交的结果。
在下一个版本的 sdk 中这应该不是问题,因为拉取请求已经被接受,从而缓解了这个问题 pr430。现在您可以回退到 sdk 的 v4.1.2。
我不确定为什么 onActivityResult 被调用了两次
两个问题都解决了,而且它们是相关的。
发生了什么但我未能理解的是 facebook 按钮有一个触发登录过程的基础事件。我在 MainActivity 上设置了另一个事件以在单击时起作用。所以,在内部,发生的事情是,facebookactivity 被创建了两次,这导致了对 onActivityResult 的两次调用。对 onActivityResult 的第一次调用使 LoginManager 的内部状态留下一个空的上下文字段(以前是 MainActivity)。第二次调用假定上下文不为空,如果为空则应用程序崩溃(内部有 Validate 验证)。
回退到以前版本的 SDK 是有效的,因为 LogginManager.context 在调用 logInWithReadPermissions 时没有被取消,呈现第二个调用 "valid"。
我有一个简单的 activity,带有一个用于登录的 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.access00(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.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.access00(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 中的上下文字段将设置为空。由于 callbackManager.onActivityResult 在某些时候调用了 logCompleteLogin,后者又根据空上下文创建了一个 LoginLogger,因此应用程序崩溃了。
为什么 onActivityResult 被调用了两次?据我所知,除了MainActivity,还有一个activity,就是FacebookActivity。
在 Facebook android SDK 的最新 v4.2.0 中,您看到的 NPE 看起来是 this 提交的结果。
在下一个版本的 sdk 中这应该不是问题,因为拉取请求已经被接受,从而缓解了这个问题 pr430。现在您可以回退到 sdk 的 v4.1.2。
我不确定为什么 onActivityResult 被调用了两次
两个问题都解决了,而且它们是相关的。
发生了什么但我未能理解的是 facebook 按钮有一个触发登录过程的基础事件。我在 MainActivity 上设置了另一个事件以在单击时起作用。所以,在内部,发生的事情是,facebookactivity 被创建了两次,这导致了对 onActivityResult 的两次调用。对 onActivityResult 的第一次调用使 LoginManager 的内部状态留下一个空的上下文字段(以前是 MainActivity)。第二次调用假定上下文不为空,如果为空则应用程序崩溃(内部有 Validate 验证)。
回退到以前版本的 SDK 是有效的,因为 LogginManager.context 在调用 logInWithReadPermissions 时没有被取消,呈现第二个调用 "valid"。