希望这篇文章能为遇到类似问题的任何人提供帮助,但这是我最近遇到的问题:
背景
我们推出了自己的 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();
}
并且片段不会被保留。我知道这相对复杂,但要点是该片段将被销毁,因为它还没有机会完全激活。