为什么我的Facebook的Android SDKlogin调用两次?

我正在使用Facebook SDK,问题是FormSubmit函数运行了两次。 它是由onCreateViewstatusCallback调用的getView函数调用的,如何解决?

 public class Home extends Fragment implements LoginListener { public View rootView; public ImageView HomeBg; public ImageView buttonLoginLogout; public TextView chi; public TextView eng; public ColorStateList oldColor; public SharedPreferences prefs; public EasyTracker tracker = null; //Facebook login private Session.StatusCallback statusCallback = new SessionStatusCallback(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { tracker = EasyTracker.getInstance(getActivity()); prefs = getActivity().getSharedPreferences("memberData", 0); getActivity().getActionBar().hide(); rootView = inflater.inflate(R.layout.home, container, false); buttonLoginLogout = (ImageView) rootView.findViewById(R.id.home_connectFB); eng = (TextView) rootView.findViewById(R.id.btn_eng); chi = (TextView) rootView.findViewById(R.id.btn_chi); if (Utility.getLocale(getActivity()).equals("TC")) { chi.setTextColor(getActivity().getResources().getColor( android.R.color.white)); oldColor = eng.getTextColors(); } else { eng.setTextColor(getActivity().getResources().getColor( android.R.color.white)); oldColor = chi.getTextColors(); } eng.setOnClickListener(setChangeLangListener("EN")); chi.setOnClickListener(setChangeLangListener("TC")); //Facebook login Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS); Session session = Session.getActiveSession(); if (session == null) { if (savedInstanceState != null) { session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState); } if (session == null) { session = new Session(getActivity()); } Session.setActiveSession(session); if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) { session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback)); } } updateView(); return rootView; } @Override public void onStart() { super.onStart(); Session.getActiveSession().addCallback(statusCallback); tracker.set(Fields.SCREEN_NAME, "Landing Page " + Utility.getLocale(getActivity())); tracker.send(MapBuilder.createAppView().build()); } @Override public void onStop() { super.onStop(); Session.getActiveSession().removeCallback(statusCallback); EasyTracker.getInstance(getActivity()).activityStop(getActivity()); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Session session = Session.getActiveSession(); Session.saveSession(session, outState); } private void updateView() { Session session = Session.getActiveSession(); if (session.isOpened()) { // get request if (!session.getAccessToken().equals(prefs.getString("token", ""))) new FormSubmit(getActivity(),this,tracker).execute("login", session.getAccessToken()); else onTaskComplete(prefs.getString("token", ""),prefs.getString("memberId", "")); } else { buttonLoginLogout.setImageResource(R.drawable.landing_btn_connect_facebook); buttonLoginLogout.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onClickLogin(); } }); } } private void onClickLogin() { Session session = Session.getActiveSession(); if (!session.isOpened() && !session.isClosed()) { session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback)); } else { Session.openActiveSession(getActivity(), this, true, statusCallback); } } private class SessionStatusCallback implements Session.StatusCallback { @Override public void call(Session session, SessionState state, Exception exception) { updateView(); } } public OnClickListener setChangeLangListener(final String lang) { OnClickListener changeLangListener = new OnClickListener() { @Override public void onClick(View arg0) { Configuration config = new Configuration(getResources().getConfiguration()); if (Utility.getLocale(getActivity()).equals("TC") && lang.equals("EN")) { tracker.send(MapBuilder.createEvent("menu_click","language", "switchEN", null).build()); config.locale = Locale.ENGLISH; chi.setTextColor(oldColor); eng.setTextColor(getActivity().getResources().getColor( android.R.color.white)); } else if (Utility.getLocale(getActivity()).equals("EN") && lang.equals("TC")) { tracker.send(MapBuilder.createEvent("menu_click","language", "switchTC", null).build()); config.locale = Locale.TRADITIONAL_CHINESE; eng.setTextColor(oldColor); chi.setTextColor(getActivity().getResources().getColor( android.R.color.white)); } getResources().updateConfiguration(config,getResources().getDisplayMetrics()); onConfigurationChanged(config); } }; return changeLangListener; } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Intent intent = getActivity().getIntent(); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); getActivity().finish(); startActivity(intent); } @Override public void onResume() { super.onResume(); AppEventsLogger.activateApp(getActivity(),getResources().getString(R.string.app_id)); } @Override public void onTaskComplete(String token, String memberId) { Toast.makeText(getActivity(), "t:" + token + "m:" + memberId, Toast.LENGTH_LONG).show(); buttonLoginLogout.setImageResource(R.drawable.landing_btn_take_a_selfie); buttonLoginLogout.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { ((LandingPage)getActivity()).tabHost.setCurrentTab(2); } }); } @Override public void onTaskFailure(String errorMsg) { Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show(); } public void saveMemberInfo(String token, String memberId){ SharedPreferences.Editor editor = prefs.edit(); editor.putString("token", token); editor.putString("memberId", memberId); editor.commit(); } } 

Solutions Collecting From Web of "为什么我的Facebook的Android SDKlogin调用两次?"

更新你的SessionStatusCallback()方法,如下所示,并检查输出。

如果有效,则将其标记为已接受的答案。

 private class SessionStatusCallback implements Session.StatusCallback { @Override public void call(Session session, SessionState state, Exception exception) { if (session.isOpened()) { updateView(); } } } 

SessionStatusCallback()方法将在每次会话从一个状态变为另一个状态时调用。

在Facebook上login之前,你的SessionState是SessionState.CLOSED 。 当您尝试在Facebook上login并且身份validation步骤成功时,您的会话将切换到SessionState.OPENING ,这次您的SessionStatusCallback()方法将被执行。

但在目前的情况下,你的会议并没有完全开放,正在开放。 所以,在此之后,当您的会话完全打开时,会话状态更改为SessionState.OPENED ,因此您的SessionStatusCallback()方法再次被调用。

这就是为什么改变你的SessionStatusCallback()方法,如上所述,它会完美的工作。

您尝试在onCreateView()恢复/打开会话。 所以当会话准备就绪时,你的callback被调用,因此updateView()被调用。

快速修复是调用updateView() onResume()而不是onCreateView() 。 然后,在updateView()内部,如果isAdded()返回false ,则检查并立即返回。 因为在这种情况下, updateView()在视图没有准备好的时候被你的callback调用。 请以FB SDK中的UserSettingsFragment为例: https : //github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/widget/UserSettingsFragment.java#L370 。

另外,我会尝试加载会议onActivityCreated()而不是onCreateView() ,以确保活动创build和准备。 https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/widget/FacebookFragment.java

我想你是两次运行相同的请求。

去掉

 updateView(); 

从onCreate开始,因为当触发statusCallback时,它将被调用