Условная навигация по фрагменту срабатывает только один раз - PullRequest
1 голос
/ 04 июля 2019

Поскольку большинство и / или все мои знания в области разработки для Android были получены из курса Google по Udacity, посвященного разработке приложений для Android с Kotlin, я столкнулся с проблемой, когда моя условная навигация срабатывает только один раз, и любые дальнейшие триггеры блокируют приложение в петля.

Надеюсь, здесь достаточно информации, чтобы избежать проблемы XY. Это также может быть слишком многословно, так как я пытался вставить резинку в текстовое поле, чтобы увидеть, не заметил ли я каких-либо явных проблем.

Приложение представляет собой отдельное приложение, которое использует компоненты архитектуры Android, привязку данных и библиотеку навигации. Он также использует Android AWS SDK, но я не думаю, что это имеет отношение к проблеме.

Следуя принципам навигации Google, конечный пункт назначения не экран входа в систему.

Экран входа в систему зависит от состояния входа в систему от AWSMobileClient верно.

Класс применения

AWSMobileClient инициализируется в приложении расширения класса

        AWSMobileClient.getInstance().initialize(applicationContext, object : Callback<UserStateDetails> {

            override fun onResult(userStateDetails: UserStateDetails) {
                Timber.i("Inside init function onResult: %s", userStateDetails.userState)

            }

            override fun onError(e: Exception) {
                Timber.e(e, "Initialization error.")
            }
        }
        )

Модель главного экрана

Проверяет состояние входа и устанавливает MutableLiveData с этим логическим значением


 private var _isSignedIn = MutableLiveData<Boolean>()

    val isSignedIn: LiveData<Boolean>
        get() = _isSignedIn


    init {
        startup()
    }

    private fun startup() {

        Timber.i(
            "Startup isSignedIn state: %s",
            AWSMobileClient.getInstance()?.isSignedIn.toString()
        )

        _isSignedIn.value = AWSMobileClient.getInstance().isSignedIn


    }

    fun logout() {
        Timber.i("Trying to logout now..")
        AWSMobileClient.getInstance().signOut()
        _isSignedIn.value = false
    }

Фрагмент главного экрана

        Timber.i("Viewmodel in oncreate")
        val homeScreenViewModel =
            ViewModelProviders.of(this)
                .get(HomeScreenViewModel::class.java)


        binding.homeScreenViewModel = homeScreenViewModel

        binding.lifecycleOwner = viewLifecycleOwner

        val navController = findNavController()


        homeScreenViewModel.isSignedIn.observe(viewLifecycleOwner, Observer { signIn ->
            if (signIn) {
                Timber.i("ifTrue isSignedIn")
                homeScreenViewModel.apiCall()
            }
            else {
                navController.navigate(HomeScreenFragmentDirections.actionHomeScreenFragmentToLoginFragment())
                Timber.i("Else isSignedIn")
            }
        })


Чистая установка приложения

Logcat


2019-07-03 15:30:38.727 I/AWSKeyValueStore: Creating the AWSKeyValueStore with key for sharedPreferences = CognitoIdentityProviderCache
2019-07-03 15:30:38.752 I/ExampleApplication$onCreate: Inside init function onResult: SIGNED_OUT
2019-07-03 15:30:38.759 I/HomeScreenFragment: Viewmodel in oncreate
2019-07-03 15:30:38.759 I/HomeScreenViewModel: Startup isSignedIn state: false
2019-07-03 15:30:38.778 I/HomeScreenFragment$onCreateView: Else isSignedIn
2019-07-03 15:30:39.182 I/HomeScreenFragment: Homescreen fragment onStop

На данный момент приложение находится на экране входа в систему, и все работает как положено.

Он

- Запущен фрагмент рабочего стола

-Проверено мое состояние входа в систему, видит, что я не вошел в систему,

-Навидит меня к экрану входа в систему.

Logcat после входа в систему

2019-07-03 15:33:39.605 I/LoginViewModel$signIn: Sign-in callback state: DONE
2019-07-03 15:33:39.605 I/LoginViewModel$signIn: Sign-in done.
2019-07-03 15:33:39.611 I/HomeScreenFragment: Viewmodel in oncreate
2019-07-03 15:33:39.618 I/HomeScreenViewModel: Startup isSignedIn state: true
2019-07-03 15:33:39.626 I/HomeScreenFragment$onCreateView: ifTrue isSignedIn
2019-07-03 15:33:39.628 I/HomeScreenFragment: Homescreen fragment onResume
2019-07-03 15:33:39.635 I/HomeScreenViewModel: Viewmodel onCleared
2019-07-03 15:33:39.635 I/HomeScreenFragment: Homescreen fragment onDestroy

Я успешно вошел в систему, вернулся на домашний экран, мое состояние входа проверено, видит, что я вошел в систему, получает данные из API и отображает их в обзор переработчика.

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

Когда я нажимаю кнопку выхода на фрагменте домашнего экрана, из окна модели вызывается функция выхода из системы

и в этот момент приложение блокируется, и мой logcat - это, повторяется до бесконечности

2019-07-03 15:40:39.756 I/HomeScreenViewModel: Trying to logout now..
2019-07-03 15:40:39.779 I/HomeScreenFragment$onCreateView: Else isSignedIn
2019-07-03 15:40:39.834 I/HomeScreenFragment: Homescreen fragment onPause
2019-07-03 15:40:39.835 I/HomeScreenFragment: Homescreen fragment onStop
2019-07-03 15:40:39.837 I/HomeScreenFragment: Viewmodel in oncreate
2019-07-03 15:40:39.838 I/HomeScreenViewModel: Startup isSignedIn state: false
2019-07-03 15:40:39.840 I/HomeScreenFragment$onCreateView: Else isSignedIn
2019-07-03 15:40:39.840 I/HomeScreenFragment: Homescreen fragment onResume
2019-07-03 15:40:39.840 I/HomeScreenViewModel: Viewmodel onCleared
2019-07-03 15:40:39.841 I/HomeScreenFragment: Homescreen fragment onDestroy

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

Запуск приложения, когда я уже вошел в систему

Если я запускаю приложение и уже вошел в систему, я остаюсь на фрагменте домашнего экрана. Когда я нажимаю кнопку выхода, я выхожу из системы и перехожу на экран входа в систему.

2019-07-03 15:43:40.417 I/ExampleApplication$onCreate: Inside init function onResult: SIGNED_IN
2019-07-03 15:43:40.438 I/HomeScreenFragment: Viewmodel in oncreate
2019-07-03 15:43:40.447 I/HomeScreenViewModel: Startup isSignedIn state: true
2019-07-03 15:43:40.485 I/HomeScreenFragment$onCreateView: ifTrue isSignedIn
2019-07-03 15:43:40.650 I/HomeScreenFragment: Homescreen fragment onResume
2019-07-03 15:43:40.835 I/OpenGLRenderer: Initialized EGL, version 1.4
2019-07-03 15:43:40.835 W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
2019-07-03 15:43:45.086 I/HomeScreenViewModel: Trying to logout now..
2019-07-03 15:43:45.115 I/HomeScreenFragment$onCreateView: Else isSignedIn
2019-07-03 15:43:45.676 I/HomeScreenFragment: Homescreen fragment onPause
2019-07-03 15:43:45.676 I/HomeScreenFragment: Homescreen fragment onStop
2019-07-03 15:43:45.758 I/art: Do partial code cache collection, code=27KB, data=29KB
2019-07-03 15:43:45.759 I/art: After code cache collection, code=24KB, data=28KB
2019-07-03 15:43:45.759 I/art: Increasing code cache capacity to 128KB

В этот момент я могу войти в систему и вернусь на домашний экран. Нажатие на кнопку выхода заблокирует приложение, пока оно не будет убито и перезапущено.

Так что мне кажется, что пока наблюдатель впервые видит значение signIn ложным, он будет правильно перемещать меня к экрану входа и обратно. Если это второй раз, однако, приложение блокируется.

EDIT:

запрошенные методы

    override fun onPause() {
        super.onPause()
        Timber.i("Homescreen fragment onPause")
    }

    override fun onStop() {
        super.onStop()
        Timber.i("Homescreen fragment onStop")

    }

    override fun onResume() {
        super.onResume()
        Timber.i("Homescreen fragment onResume")

    }

    override fun onDestroy() {
        super.onDestroy()
        Timber.i("Homescreen fragment onDestroy")

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...