Не одобряется ли выход из приложения? - PullRequest
1108 голосов
/ 09 января 2010

Продолжая попытки освоить Android, я просто прочитал следующее :

Вопрос: Есть ли у пользователя выбор убить приложение если мы не добавим пункт меню, чтобы убить его? Если такой опции не существует, как пользователь закрывает приложение?

Ответ: (Romain Guy): Пользователь этого не делает, система обрабатывает это автоматически. Вот для чего нужен жизненный цикл активности (особенно onPause / onStop / onDestroy). Что бы вы ни делали, не ставьте кнопку «выйти» или «выйти» из приложения. Это бесполезно с моделью приложения Android. Это также противоречит принципам работы основных приложений.

Хе-хе, за каждый мой шаг в мире Android я сталкиваюсь с какой-то проблемой = (

По-видимому, вы не можете закрыть приложение в Android (но система Android может очень хорошо полностью уничтожить ваше приложение, когда оно будет похоже). Что с этим? Я начинаю думать, что невозможно написать приложение, которое функционирует как «обычное приложение» - что пользователь может выйти из приложения, когда он / она решит это сделать. Это не то, на что должна полагаться ОС.

Приложение, которое я пытаюсь создать, не является приложением для Android Market. Это не приложение для «широкого использования» широкой публикой, это бизнес-приложение, которое будет использоваться в очень узкой сфере бизнеса.

Я действительно с нетерпением ждал разработки для платформы Android, поскольку она решает множество проблем, существующих в Windows Mobile и .NET. Тем не менее, последняя неделя была для меня своего рода поворотом ... Надеюсь, мне не придется отказываться от Android, но сейчас это выглядит не очень хорошо = (

Есть ли способ для действительно выйти из приложения?

Ответы [ 38 ]

1253 голосов
/ 09 января 2010

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

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

Миллионы людей совершенно довольны моделью, в которой среда закрывает приложение по мере необходимости. Эти пользователи просто не думают о «закрытии» приложения Android, равно как и о «прекращении» веб-страницы или «прекращении» термостата.

Пользователи iPhone во многом аналогичны, в том смысле, что нажатие кнопки iPhone не обязательно «чувствует», как приложение было закрыто, так как многие приложения iPhone поднимаются с того места, где пользователь остановился, даже если приложение действительно было закрыто ( поскольку в настоящее время iPhone поддерживает только одно стороннее приложение).

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

Я не знаю, что означает «списки с задачами, которые всегда должны быть там», но «данные, передаваемые на устройство» - приятная выдумка, которая ни в коем случае не должна выполняться какой-либо деятельностью. Используйте запланированное задание (через AlarmManager), чтобы обновить данные для максимальной надежности.

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

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

Например, мы хотим проверить обновления при выходе из приложения

Это ошибка в любой операционной системе. Насколько вы знаете, причина того, что ваше приложение «закрывается», заключается в том, что ОС закрывается, и тогда ваш процесс обновления завершится ошибкой. Как правило, это не очень хорошая вещь. Либо проверяйте обновления при запуске, либо проверяйте обновления полностью асинхронно (например, с помощью запланированной задачи), но не при выходе.

Некоторые комментарии предполагают, что удар по кнопка назад не убивает приложение при все (см. ссылку в моем вопросе выше).

Нажатие кнопки НАЗАД не «убивает приложение». Он завершает действие, которое было на экране, когда пользователь нажал кнопку НАЗАД.

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

Тогда и веб-приложения не могут. Или WebOS , если я правильно понимаю их модель (у меня еще не было возможности поиграть с ней). Во всех этих случаях пользователи ничего не «прекращают» - они просто уходят. iPhone немного отличается тем, что в настоящее время он позволяет запускать только одну вещь за раз (за некоторыми исключениями), и поэтому процесс ухода подразумевает довольно немедленное завершение приложения.

Есть ли способ для меня действительно бросить приложение?

Как и все остальные говорили вам, пользователи (через BACK) или ваш код (через finish()) могут закрыть вашу текущую деятельность. Пользователям, как правило, больше ничего не нужно для правильно написанных приложений, больше, чем им нужна опция «выход» для использования веб-приложений.


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

Например, усиливается движение, чтобы попытаться исключить понятие «файл». Большинство веб-приложений не заставляют пользователей думать о файлах. Приложения для iPhone обычно не заставляют пользователей думать о файлах. Приложения Android обычно не заставляют пользователей думать о файлах. И так далее.

Точно так же растет стремление избавиться от понятия «прекращение» приложения. Большинство веб-приложений не заставляют пользователя выходить из системы, а неявно выходят из системы после определенного периода бездействия. То же самое с Android и, в меньшей степени, iPhone (и, возможно, WebOS).

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

Например, в некоторых средах разработки, таких как Hypercard и Smalltalk, приложение и инструменты разработки были объединены в одной установке. Эта концепция не получила широкого распространения за пределами языковых расширений приложений (например, VBA в Excel , Lisp в AutoCAD ). Поэтому разработчики, которые придумали ментальные модели, которые предполагали наличие инструментов разработки в самом приложении, должны были либо изменить свою модель, либо ограничить себя средами, в которых их модель была бы верна.

Итак, когда вы пишете:

Наряду с другими грязными вещами, которые я обнаружил, я думаю, что разработка наше приложение для Android не собирается случается.

Похоже, что сейчас это к лучшему, для вас. Точно так же я бы посоветовал вам не пытаться портировать ваше приложение в Интернет, поскольку некоторые из тех же проблем, о которых вы сообщали в Android, вы найдете и в веб-приложениях (например, без «завершения»). Или, наоборот, когда-нибудь, если вы do перенесете свое приложение в Интернет, вы можете обнаружить, что поток веб-приложений может лучше подходить для Android, и вы можете вернуться к порту Android в это время.

288 голосов
/ 13 апреля 2010

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

System.exit() не убивает ваше приложение, если в стеке имеется более одного действия. На самом деле происходит то, что процесс завершается и сразу же перезапускается с одним меньшим количеством действий в стеке. Это также происходит, когда приложение закрывается в диалоговом окне Force Close или даже когда вы пытаетесь завершить процесс из DDMS. Насколько мне известно, это совершенно недокументированный факт.

Короткий ответ: если вы хотите выйти из приложения, вы должны отслеживать все действия в вашем стеке и finish() ВСЕ из них, когда пользователь хочет выйти (и нет, нет никакого способа итерировать по стеку Activity, так что вам придется управлять всем этим самостоятельно). Даже это на самом деле не убивает процесс или любые свисающие ссылки, которые вы можете иметь. Это просто заканчивает деятельность. Кроме того, я не уверен, работает ли Process.killProcess(Process.myPid()) лучше; Я не проверял это.

Если, с другой стороны, для вас нормально, чтобы в вашем стеке оставались какие-то действия, есть другой метод, который делает ваши вещи очень простыми: Activity.moveTaskToBack(true) просто отодвинет на задний план ваш процесс и покажет домашний экран.

Длинный ответ включает в себя объяснение философии этого поведения. Философия рождается из ряда предположений:

  1. Прежде всего, это происходит только тогда, когда ваше приложение находится на переднем плане. Если это в фоновом режиме, процесс будет просто нормально завершен. Однако, если она находится на переднем плане, ОС предполагает, что пользователь хочет продолжать делать то, что он / она делал. (Если вы пытаетесь убить процесс из DDMS, сначала вы должны нажать кнопку «Домой», а затем убить ее)
  2. Это также предполагает, что каждое действие не зависит от всех других действий. Это часто так, например, в том случае, если ваше приложение запускает активность браузера, которая является совершенно отдельной и не была написана вами. Действия браузера могут создаваться или не создаваться для одной и той же задачи в зависимости от ее атрибутов манифеста.
  3. Предполагается, что каждое из ваших действий является полностью самостоятельным и может быть убито / восстановлено в любой момент. (Мне скорее не нравится это конкретное предположение, так как в моем приложении много операций, которые зависят от большого объема кэшированных данных, слишком больших, чтобы их можно было эффективно сериализовать во время onSaveInstanceState, но что делать?) Для большинства хорошо написанных приложений Android это должно быть правдой, поскольку вы никогда не знаете, когда ваше приложение будет убито в фоновом режиме.
  4. Последний фактор является не столько предположением, сколько ограничением ОС: явное уничтожение приложения - это то же самое, что и аварийное завершение приложения, и то же самое, что и Android, убивающее приложение для восстановления памяти. Кульминацией этого является наш переворот: поскольку Android не может определить, было ли приложение закрыто, или оно зависло, или оно было убито в фоновом режиме, оно предполагает, что пользователь хочет вернуться с того места, где они остановились, и поэтому ActivityManager перезапускает процесс. 1029 *

Когда вы думаете об этом, это подходит для платформы. Во-первых, это именно то, что происходит, когда процесс убивается в фоновом режиме, и пользователь возвращается к нему, поэтому его необходимо перезапустить с того места, где он остановился. Во-вторых, это то, что происходит, когда приложение аварийно завершает работу и представляет ужасное диалоговое окно Force Close.

Скажем, я хочу, чтобы мои пользователи могли делать снимки и загружать их. Я запускаю Camera Activity из своей активности и прошу вернуть изображение. Камера помещается в верхнюю часть моей текущей задачи (а не создается в своей собственной задаче). Если у камеры есть ошибка, и она вылетает, это должно привести к краху всего приложения? С точки зрения пользователя, только Камера вышла из строя, и они должны быть возвращены к предыдущей активности. Таким образом, он просто перезапускает процесс со всеми теми же действиями в стеке, за исключением камеры. Поскольку ваши действия должны быть спроектированы таким образом, чтобы их можно было убить и восстановить одним махом, это не должно быть проблемой. К сожалению, не все приложения могут быть спроектированы таким образом, поэтому является проблемой для многих из нас, независимо от того, что вам скажет Ромэн Гай или кто-то еще. Итак, нам нужно использовать обходные пути.

Итак, мой заключительный совет:

  • Не пытайтесь убить процесс. Либо позвоните finish() на все мероприятия или позвоните moveTaskToBack(true).
  • Если ваш процесс завершается сбоем или уничтожается, и если, как и мне, вам нужны данные, которые были в памяти, которые сейчас потеряны, вам необходимо вернуться к корневому действию. Для этого вам следует вызвать startActivity() с намерением, содержащим флаг Intent.FLAG_ACTIVITY_CLEAR_TOP.
  • Если вы хотите убить ваше приложение с точки зрения Eclipse DDMS, лучше не быть на переднем плане, либо оно само перезапустится. Сначала вы должны нажать кнопку Home, и , а затем завершить процесс.
174 голосов
/ 12 июля 2010

Все мои приложения имеют кнопки выхода ... и я довольно часто получаю положительные отзывы от пользователей из-за этого.Мне все равно, если платформа была разработана таким образом, чтобы приложения не нуждались в них.Говорить «не кладите их туда» довольно нелепо.Если пользователь хочет выйти ... Я предоставляю им доступ именно для этого.Я не думаю, что это снижает эффективность работы Android и кажется хорошей практикой.Я понимаю жизненный цикл ... и я заметил, что Android не справляется с этим ... и это основной факт.

141 голосов
/ 30 июля 2010

Хватит думать о вашем приложении как о монолитном приложении. Это набор экранов пользовательского интерфейса, с которыми пользователь может взаимодействовать с вашим «приложением» и «функциями», предоставляемыми через службы Android.

Знание того, что "делает" ваше загадочное приложение, не очень важно. Давайте предположим, что он туннелируется в какую-то сверх защищенную корпоративную интрасеть, выполняя некоторый мониторинг или взаимодействие, и остается в системе до тех пор, пока пользователь не «выйдет из приложения». Поскольку ваш ИТ-отдел командует им, пользователи должны очень хорошо знать, когда они находятся в или вне интранета. Следовательно, ваше мышление важно, чтобы пользователи "уходили".

Это просто. Создайте службу, которая помещает текущее уведомление в панель уведомлений, говорящее «Я в интрасети, или я работаю». Пусть эта служба выполнит все функции, которые вам необходимы для вашего приложения. Есть действия, которые связаны с этой службой, чтобы позволить вашим пользователям получать доступ к битам пользовательского интерфейса, которые им нужны для взаимодействия с вашим «приложением». И есть кнопка «Меню Android» -> «Выход» (или выход из системы, или что-то еще), которая указывает службе завершить работу, а затем закрывает само действие.

Это для всех намерений и целей именно то, что вы говорите, что вы хотите. Сделано способом Android. Посмотрите на Google Talk или Google Maps Navigation для примеров такого «выхода» возможного менталитета. Единственное отличие состоит в том, что нажатие кнопки «Назад» из-за вашей активности может привести к тому, что процесс UNIX окажется в ожидании на тот случай, если пользователь захочет восстановить ваше приложение. Это действительно ничем не отличается от современной операционной системы, которая кэширует недавно использованные файлы в памяти. После выхода из программы Windows наиболее вероятные ресурсы, которые ей необходимы, все еще находятся в памяти, ожидая замены другими ресурсами, поскольку они загружаются теперь, когда они больше не нужны. Android это то же самое.

Я действительно не вижу твоей проблемы.

70 голосов
/ 20 сентября 2010

Это интересная и проницательная дискуссия с участием многих экспертов. Я чувствую, что этот пост должен быть зациклен на главном веб-сайте разработки Android, потому что он вращается вокруг одного из основных дизайнов ОС Android.

Я также хотел бы добавить свои два цента здесь.

До сих пор я был впечатлен тем, как Android обрабатывает события жизненного цикла, привнося концепцию веб-опыта в нативные приложения.

Сказав, что я все еще считаю, что должна быть кнопка Выйти . Зачем? ... не для меня, Теда или кого-либо из технических гуру здесь, но с единственной целью удовлетворения спроса конечного пользователя.

Хотя я не большой поклонник Windows, но давным-давно они представили концепцию, к которой привыкло большинство конечных пользователей (кнопка X) ... "Я хочу прекратить запуск виджета, когда" я "хочу" .

Это не значит, что кто-то (ОС, разработчик?) Позаботится об этом по своему усмотрению ... это просто означает "где моя красная кнопка Х, к которой я привык". Мое действие должно быть аналогичным «завершить вызов нажатием кнопки», «выключить устройство нажатием кнопки» и т. Д. И т. Д. - это восприятие. Это само по себе приносит удовлетворение тем, что мои действия действительно достигают своей цели.

Несмотря на то, что разработчик может подделать это поведение, используя приведенные здесь предложения, восприятие все еще остается, то есть приложение должно полностью перестать функционировать (сейчас) из независимого, доверенного и нейтрального источника (ОС) по требованию конечного пользователя.

36 голосов
/ 09 января 2010

Вы можете выйти, нажав кнопку Back или позвонив по номеру finish() на вашем Activity. Просто позвоните finish() из MenuItem, если хотите явно убить его.

Ромен не говорит, что это невозможно, просто бессмысленно & mdash; пользователям не нужно заботиться о прекращении или сохранении своей работы или чего-либо еще, поскольку работа жизненного цикла приложения побуждает вас писать умное программное обеспечение, которое автоматически сохраняет и восстанавливает свое состояние независимо от того, что происходит.

31 голосов
/ 05 февраля 2011

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

Тед отметил, что одним из самых скачиваемых приложений на Маркете является App Killer. Люди получают немного дополнительного серотонина, когда они выходят из приложений. Они привыкли к этому с настольным компьютером / ноутбуком. Это заставляет вещи двигаться быстро. Это держит процессор прохладным и вентилятор от включения. Он потребляет меньше энергии.

Если вы считаете, что мобильное устройство представляет собой гораздо меньший корабль, то вы особенно можете оценить его стимул «выбросить за борт то, что вам больше не нужно». Теперь разработчики Android считают, что ОС знает лучше, а выход из приложения - это антиквариат. Я искренне поддерживаю это.

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

29 голосов
/ 10 января 2010

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

Я предлагаю вам прочитать о деятельности и услугах. Прекратите использовать термин «приложение» и начните ссылаться на компоненты, то есть активность, сервис. Я думаю, вам просто нужно больше узнать о платформе Android; это изменение мышления от стандартного приложения для ПК. Тот факт, что ни в одном из ваших сообщений не было слова «Активность» (за исключением цитаты из часто задаваемых вопросов, т. Е. Не ваших слов), говорит о том, что вам нужно прочитать еще немного.

23 голосов
/ 22 апреля 2012

Запись в блоге Когда включать кнопку выхода в приложения для Android (подсказка: никогда) объясняет это далеко, далеко лучше, чем я могу Жаль, что каждый разработчик Android уже прочитал его.

Выдержки:

По моему опыту [пользователи] действительно хотят: Однозначный способ гарантировать, что приложение перестанет потреблять ресурсы (батарея, циклы процессора, передача данных и т. Д.).

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

  • В большинстве случаев кнопка выхода просто вызывает Activity.finish(). Это точно эквивалентно нажатию кнопки "назад". Точно. Службы продолжают работать, а опросы продолжаются. Пользователи могут подумать, что они убили приложение, но они этого не сделали, и скоро они будут еще более раздражены.
  • Поведение при выходе теперь неоднозначно. Должна ли кнопка «Выход» просто закрыть действие, или она также должна остановить все связанные службы, получатели и сигналы тревоги? Что должен Back делать? Что произойдет, если вместо этого они нажмут Home ? Что произойдет, если в вашем приложении есть виджет? Должна ли кнопка выхода остановить это обновление тоже?

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

Продолжайте читать статью полностью.

20 голосов
/ 09 сентября 2013

Ответ: (Romain Guy): пользователь этого не делает, система обрабатывает это автоматически. Это то, что жизненный цикл деятельности (особенно onPause / onStop / onDestroy) для. Что бы вы ни делали, не ставьте кнопка «выйти» или «выйти». Это бесполезно с Android модель приложения. Это также противоречит тому, как основные приложения работа.

1: Полный выход из приложения может быть в целом обязательным, но это не бесполезно. Что, если у окон не было выбора выхода? Система будет работать очень медленно, так как память заполнена, и ОС придется угадывать, с какими программами вы работали. Мне все равно, что скажут Ромейн Гай или даже Ларри Пейдж и Сергей Брин - это неоспоримые факты: системы работают медленнее, когда им приходится убивать задачи, чтобы получить память перед запуском нового приложения. Вы просто не можете сказать мне, что не нужно времени, чтобы убить приложение! Даже свет от далеких звезд требует времени ... * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 100 '* * * * * * * *' s 's некоторое использование, чтобы позволить пользователю полностью закрыть приложения

2: В отличие от того, как работают основные приложения? Что это должно означать? Когда я закончила запуск приложения, оно больше не выполняет никакой работы ... Оно просто ждет, когда ОС его убьет, когда потребуется память.

Таким образом, существует четкое различие между минимизацией и выходом, и ни один из них не подходит для другого. Мы оставляем отвертку в каждом винте? Или ключ в каждой двери? Оставляем ли мы все наши приборы на высоте, пока не сломается выключатель, и нам нужно включить другой прибор? Разве мы оставляем посудомоечную машину полной посуды и вынимаем достаточно только каждый раз, чтобы освободить место для новых грязных? Оставим ли мы все машины на подъездной дороге, пока - о, неважно.

Если пользователь хочет свернуть приложение, лучше всего свернуть его. Если пользователь хочет выйти из приложения, то лучше всего выйти из него.

Это нахмурилось? Это точка зрения Android - они нахмурились. И многие многие независимые новички-разработчики Android нахмурились.

Но когда дело доходит до этого, есть хорошее кодирование и плохое кодирование. Есть хорошие модели программных потоков и есть плохие модели программных потоков.

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

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

Точно так же, если вы играете в игру, и телефон звонит, да. Приостановите игру и продолжайте работать. Но если пользователь закончил с игрой какое-то время, то он обязательно должен выйти.

Кнопка выхода в некоторых приложениях должна быть больше впереди, чем в других. Например, игры или программы, в которых пользователь, вероятно, захочет полностью выйти, должны иметь очевидный выход. Другие программы, такие как, возможно, программы электронной почты, где выход маловероятен (так что он может продолжать проверять электронную почту) - эти программы не должны тратить пространство экрана первичного управления с опцией выхода, но для хорошего потока программ, это должен иметь вариант выхода. Что если кто-то решит, что не хочет, чтобы его почтовая программа пыталась проверить электронную почту, когда он находится в зоне с плохим покрытием, или, возможно, во время разговора по Skype или чего-то еще? Позвольте им выйти из программы электронной почты, если они хотят!

Приостановка и выход - две жизненно важные задачи, и ни одна не выполняет роль другой.

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