onActivityResult调用了两次

时间:2015-06-09 15:39:40

标签: android facebook-android-sdk

我有一个简单的活动,使用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。

2 个答案:

答案 0 :(得分:3)

这两个问题都已解决,而且它们是相关的。

发生了什么,我无法理解的是,facebook按钮有一个触发登录过程的基础事件。我在MainActivity上设置了另一个事件来执行click。因此,在内部,发生的事情是,facebookactivity正在创建两次,导致两次调用onActivityResult。对onActivityResult的第一次调用使LoginManager的内部状态保留了一个空的上下文字段(以前是MainActivity)。第二个调用假定上下文不为null,如果它是崩溃应用程序(内部有Validate验证)。

回退到以前版本的SDK,因为在调用logInWithReadPermissions时,LogginManager.context没有被取消,导致第二个调用“有效”。

答案 1 :(得分:2)

在Facebook android sdk的最新v4.2.0中,您看到NPE看起来是this提交的结果。

在下一版本的sdk中不应该是一个问题,因为已经接受了拉取请求,这可以缓解此问题pr430。现在你可以回到sdk的v4.1.2。

我不确定为什么onActivityResult被调用两次