Блокировать выполнение над переменной (вариант использования TTS), кроме операторов журнала (жуткий)

Я хочу, чтобы логическое значение было истинным перед выполнением блока кода, и я хочу, чтобы оно фактически блокировало поток, в котором оно находится. Вариант использования достаточно прост. У меня есть вариант использования TTS в моем приложении, и я хочу иметь последовательное выполнение, когда TTS говорит, затем что-то происходит, и он говорит снова и так далее, но дело в том, что это полностью зависит от времени. Мне нужно запустить таймер, как только TTS закончит говорить, но оказывается, что метод speak(...) неблокирующий (видимо), и поэтому в момент, когда он говорит, управление переходит на следующую строку.

Чтобы справиться с этим, я раздобыл переменную isSpeaking, реализованную с помощью deprecatedOnUtteranceCompletedListener, и она, как всегда, отлично работает.

Тем не менее, это СУПЕР-СПЕЦИАЛЬНОЕ исполнение, которое я вижу в своей реализации. Переменная, как я упоминал ранее, отлично отслеживает речь, но когда я применяю свой цикл таким образом,

while(speaking){
  continue
}

ОН БЛОКИРУЕТСЯ, ПОКА НЕ ПРОИСХОДИТ РЕЧЬ, А ЗАТЕМ КОНТРОЛЬ ПРОСТО ИСЧЕЗАЕТ!!!,

Я помещаю оператор журнала сразу после этого цикла, и как только условие становится ложным, т. е. цикл прерывается, эта часть кода никогда не регистрируется. На самом деле, после этого он вообще ничего не делает. Вроде исполнение "потерял", где-то после этого. Приложение даже не зависает. Я использую Jetpack-Compose, поэтому все анимации с бесконечным повторением работают нормально, но после этого приложение ничего не делает.

Но вот в чем дело — если я заменю свой continue просто утверждением Log, это волшебным образом сработает. ВСЕ РАБОТАЕТ, АБСОЛЮТНО НЕТ НЕОБЫЧНЫХ НАБЛЮДЕНИЙ ПРИ ДОБАВЛЕНИИ ОДИН LOG STATMENT.

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

Я говорю, что это работает:

while(speaking){
 Log.i("WHY?", "speaking")
}

Это больно, так как я не могу использовать вызовы Log в своем производственном программном обеспечении, официальная документация строго запрещает это. Помощь!

Вскоре я опубликую реализацию компоновки, чтобы лучше визуализировать эффект.

Richard Onslow Roper 17.05.2022 04:12
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
1
19
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы неправильно обрабатываете условие многопоточности, и это будет проблемой. Цикл, который вы используете, ожидает изменения переменной в другом потоке. Во-первых, это работает, только если переменная изменчива. Если нет, интерпретатор не знает, что ему нужно перезагрузиться из памяти, и этот цикл никогда не закончится. Во-вторых, то, что вы делаете, называется занятым ожиданием и является ПЛОХОЙ идеей для проблем с батареей (и если это делается в потоке пользовательского интерфейса, это может привести к тому, что ваше приложение перестанет отвечать на запросы или даже будет убито сторожевым таймером). Вместо этого, если это не поток пользовательского интерфейса, вы должны использовать механизм сигнализации, такой как семафор. Это позволит вам ждать, не простаивая ЦП, пока не будет дан сигнал. Если это поток пользовательского интерфейса, вы вообще не должны этого делать. Вместо этого вы должны заставить прослушиватель речи отправить сообщение обработчику в поток пользовательского интерфейса и выполнить все, что находится после цикла, в ответ на это сообщение.

У вас случайно нет находчивых ссылок, где я могу изучить все это? Кроме того, как упоминалось выше, я использую Jetpack-Compose в своих проектах, поэтому сопрограммы используются повсеместно. Я использую диспетчер ввода-вывода для запуска этого, который, как вы, возможно, знаете, порождает свой собственный пул потоков, поэтому эта работа определенно выполняется вне потока пользовательского интерфейса.

Richard Onslow Roper 17.05.2022 04:50

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

Gabe Sechan 17.05.2022 04:51
javatpoint.com/volatile-keyword-in-java Это описание ключевого слова volatile и объяснение того, почему оно используется.
Gabe Sechan 17.05.2022 04:52

Мой основной фокус - необъяснимое дело с тем фактом, что «с / без волатильности это работает, если добавляется оператор журнала, и абсолютно не работает, когда используется просто продолжение или пустой цикл while». Я могу согласиться с тем фактом, что волатильность имеет значение, и это действительно могло быть фактором, вызывающим, казалось бы, бесконечный цикл, но ПОЧЕМУ, без каких-либо изменений в природе переменной, добавление одного вызова Log заставляет цикл работать так, как ожидалось? Это необъяснимый момент, который я хотел бы прояснить, сэр. Спасибо

Richard Onslow Roper 17.05.2022 05:02

без volatile интерпретатор может выбрать, загружать его из памяти или нет. Не будет, если не нужно, будет, если понадобится. Оператор журнала заставил что-то в интерпретаторе решить, что ему нужно снова загрузить его из памяти. Скорее всего, он сбрасывал регистры ЦП с помощью вызова функции, или используемый им ABI не требовал вызова функции для восстановления регистра, который он использовал для хранения этого значения. Но там не на что можно положиться, другой интерпретатор Java или даже другая версия этого могут сделать другой выбор.

Gabe Sechan 17.05.2022 05:07

Вау... Ужасно, но... Я приму это как правильный ответ.

Richard Onslow Roper 17.05.2022 05:29

Другие вопросы по теме