0

希望这篇文章能为遇到类似问题的任何人提供帮助,但这是我最近遇到的问题:

背景

我们推出了自己的 facebook 登录片段,并使其与 3.0 sdk 中的示例相对相似。该片段是一个 setRetainInstance(true) 片段,预计来自 facebook SDK 的回调将传递到相关片段。登录过程将在片段的 onCreate() 方法中启动,如下所示:

  if (sessionIsOpenable(session)) {
      session.openForRead(new Session.OpenRequest(this).setCallback(mReadStatusCallback).setPermissions(mReadPermissions));
  } else if (SessionState.OPENING != session.getState()) {
      Session.openActiveSession(getActivity(), this, true, mReadStatusCallback);
  }

遇到的问题

这似乎只发生在用户第一次登录/授权尝试时,FB 或我们的本地缓存中不存在缓存的访问令牌。会发生的情况是,当用户接受读取权限请求时,facebook SDK 会调用我们的回调,但我们的片段不会执行任何额外的处理,因为我们在检查中保护了额外的工作,如下所示:

if (isResumed()) {
  // Do processing (adding fragments, etc...)
}

我们看到了从暂停到恢复的片段转换,但它是在片段的一个新实例上,而不是启动登录尝试的那个实例。当我在调试过程中删除了对 isResumed() 的检查时,由于没有附加片段,代码会崩溃。

原因 我们发现,您绝对不能从片段的 onCreate() 方法执行会话初始化,因为 facebook 将启动它自己的活动,这将导致片段被 FragmentManager 设为非活动状态(当我们的活动恢复时,会导致一个新的片段实例被添加到片段管理器中)。这是因为 FragmentManager 在初始化片段时这样做:

if (!f.mRetaining) {
  f.performCreate(f.mSavedFragmentState);
}
  f.mRetaining = false;

片段将进行的下一个转换将调用它:

 if (!f.mRetaining) {
   f.performDestroy();
 }

并且片段不会被保留。我知道这相对复杂,但要点是该片段将被销毁,因为它还没有机会完全激活。

4

1 回答 1

0

解决方法

我们已经能够运行可运行的 onResume(),因此我们将初始化代码添加到 onCreate() 中的可运行,并且可运行的可在 onResume() 中执行。

  mResumeRunnable = new Runnable() {

        @Override
        public void run() {
            if (sessionIsOpenable(session)) {
                session.openForRead(new Session.OpenRequest(AbstractFacebookLoginFragment.this)
                        .setCallback(mReadStatusCallback).setPermissions(mReadPermissions));
            } else if (SessionState.OPENING != session.getState()) {
                Session.openActiveSession(getActivity(), AbstractFacebookLoginFragment.this,
                        true, mReadStatusCallback);
            }
  };

@Override
public void onResume() {
    super.onResume();

    if (null != mResumeRunnable) {
        mResumeRunnable.run();
        mResumeRunnable = null;
    }
}

希望这可以帮助遇到类似问题的人。

于 2013-06-19T19:05:37.787 回答