2013-06-19 2 views
0

Надеются, этот пост будет служить помощником для тех, кто работает в подобную проблему, но вот проблема, которую я недавно столкнулся:Facebook Войти с setRetainInstance фрагмента

фона

Выкатывает собственный фейсбук фрагмент входа и сделали его относительно похожим на образцы из 3.0 sdk. Фрагмент представляет собой фрагмент setRetainInstance (true), и ожидается, что обратные вызовы из SDK facebook будут доставлены в соответствующий фрагмент. Процесс Логин будет стартовал в методе 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(); 
} 

И фрагмент не будет сохранен. Я знаю, что это относительно сложно, но суть в том, что фрагмент будет уничтожен, потому что у него еще не было возможности полностью активироваться.

ответ

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; 
    } 
} 

Надеюсь, это поможет кому-то, имеющему аналогичную проблему.

Смежные вопросы