Android Volley - изменения ориентации

Как мы можем справиться с изменениями ориентации, Activities/Fragments остановить/возобновить с помощью Volley?

Я знаю, что для запросов GET ответ будет кэшироваться, и во второй раз, когда мы попытаемся сделать этот запрос, мы получим кешированный ответ. (ЕСЛИ сервер отправляет соответствующие HTTP-заголовки)

Но как насчет POST? Предположим, что я делаю запросы POST (т.е. Регистр, который я хочу выполнить только один раз), мое приложение переходит в фоновый режим, запрос завершается, пока приложение все еще находится в фоновом режиме, а затем я возвращаюсь в приложение. Как мне получить Response для этого Request или как я могу подключиться к нему, если он все еще ожидает?

AFAIK в этом почти не поддерживается, в Volley. Я прав? Есть ли простой способ решить вышеупомянутый сценарий, используя Volley?

Ответы

Ответ 1

Volley не предоставляет механизм для этого из коробки, но вы можете посмотреть в библиотеку Square Otto для Android, она предназначена для того, чтобы обрабатывать такие ситуации, как ваши элегантно.

Внедрите Listener для запроса Volley, чтобы он отправил успешный ответ на шину, завернутый в объект события, такой как "RegisterEventSuccess" (вы сами определяете это). Пусть ваши действия или фрагменты подписываются на этот тип события с помощью механизма Otto @Subscribe. Если, например, одно действие запускает запрос Volley и умирает из-за изменения ориентации экрана, другой экземпляр Activity (также зарегистрированный на шине Otto) может затем получить событие, которое содержит ответ запроса Volley.

Надеюсь, это было полезно.

Ответ 2

Теперь я попытался решить проблему @kyle-ivey в том, что отклики, поступающие между onPause() и onResume(), отбрасываются. Это реальная проблема, поскольку я испытал ее в реальном приложении.

Мой подход основывается на шаблоне шины событий, реализованном в ответе Томаса Моермана, хотя я повторил пример приложения с нуля. Это зависит от Отчётной библиотеки событий Отто, Gson и Volley. Он реализован в IntelliJ 13 Ultimate с использованием Maven tom для решения зависимостей.

Решение: Я добавляю к предыдущим ответам класс, который действует как буфер ответа HTTP, который берет на себя ответственность за прослушивание событий во время перехода Activity. Когда это будет сделано, активность будет активно опроса для любых ответов, которые могли быть получены, когда действие было отключено от шины событий. Он перехватывает вкл/выкл в onPause и onResume -events рядом с регистрацией события-шины следующим образом:

@Override
protected void onPause() {
    super.onPause();
    ServiceLocator.ResponseBuffer.startSaving(); // The buffer takes over
    ServiceLocator.EventBus.unregister(this);    // Unregistering with Otto
}

@Override
protected void onResume() {
    ServiceLocator.EventBus.register(this);         // Re-registering
    ServiceLocator.ResponseBuffer.stopAndProcess(); // Process any responses buffered
}

Вот реализация класса ResponseBuffer.

Предостережение 1. Если активность никогда не возобновляется, и ни stopAndProcess(), ни stopAndPurge() не вызывается в любой будущей деятельности, буфер может быть источником утечки памяти. Имейте в виду, как вы его используете. Безопасным шаблоном было бы иметь stopAndProcess() в onResume() во всех ваших действиях.

Caveat 2: он не является потокобезопасным. Если на линии между тем, где она хранится, будет переключаться контекст, и он отменяет регистрацию шины события, он может получить событие дважды или нулевое время.

Пример включает в себя некоторый тестовый код в виде интерфейса и классов поддержки, но основные классы, которые вам нужны, если вы хотите использовать этот шаблон в отдельных проектах, являются следующими в следующих пакетах:

  • nilzor.ottovolley.core
  • nilzor.ottovolley.messages

См. github-repository OttoVolleyDoneRight для полного примера с пользовательским интерфейсом для тестирования.

Ответ 3

Там есть простое решение, которое решило мою проблему с загрузкой данных из сети с помощью библиотеки Volley. Если ваше приложение использует фрагменты из-за рекомендаций Google, чем все, что вы должны сделать, чтобы предотвратить сбой, если пользователь поворачивает экран во время загрузки данных, ставится setRetainInstance(true); в onCreateView метод вашего фрагмента (-s).

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View theView = inflater.inflate(R.layout.fragment_studios, container, false);
    setRetainInstance(true);
    lvStudios = (ListView) theView.findViewById(R.id.lvStudios);
  return theView;
}

Ответ 4

Предположим, у вас есть кнопка входа в систему, При нажатии Btn вашего вызывающего сервера через залп, Внезапно, если ориентация экрана изменяется, залп перезапускается, и приложение вылетает.

Так что мое решение: при первом нажатии на экран блокировки ориентации Btn, когда приходит волейбол, вы разблокируете ориентацию экрана...

...........Вот по клику --- lockDeviceRotation (true)//Блокировка в ответ - lockDeviceRotation (false)//разблокировать

public void lockDeviceRotation(boolean value) {
    if (value) {
        int currentOrientation = getResources().getConfiguration().orientation;
        if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
        }
    } else {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
        }
    }
}