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() のチェックを削除すると、フラグメントがアタッチされていないためにコードがクラッシュしました。

理由 私たちが発見したことは、facebook が独自のアクティビティを起動し、FragmentManager によってフラグメントが非アクティブになるため、フラグメントの onCreate() メソッドからセッションの初期化を実行することは絶対にできないということです (これにより、アクティビティが再開したときに新しいフラグメント インスタンスがフラグメント マネージャーに追加されます)。これは、フラグメントの初期化時に 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 に答える