Sair de um aplicativo é mal visto?

1153

Seguindo em frente na minha tentativa de aprender Android, acabei de ler o seguinte :

Pergunta: O usuário tem a opção de matar o aplicativo, a menos que tenhamos uma opção de menu para matá-lo? Se essa opção não existir, como o usuário encerra o aplicativo?

Resposta: (Romain Guy): O usuário não, o sistema lida com isso automaticamente. É para isso que serve o ciclo de vida da atividade (especialmente onPause / onStop / onDestroy). Não importa o que você faça, não coloque um botão de aplicativo "sair" ou "sair". É inútil com o modelo de aplicativo do Android. Isso também é contrário ao funcionamento dos aplicativos principais.

Hehe, a cada passo que dou no mundo Android, encontro algum tipo de problema = (

Aparentemente, você não pode sair de um aplicativo no Android (mas o sistema Android pode muito bem destruir totalmente seu aplicativo sempre que lhe apetecer). O que há com isso? Estou começando a pensar que é impossível escrever um aplicativo que funcione como um "aplicativo normal" - que o usuário possa sair do aplicativo quando decidir fazê-lo. Isso não é algo que deve ser confiado ao sistema operacional.

O aplicativo que estou tentando criar não é um aplicativo para o Android Market. Não é um aplicativo de "amplo uso" pelo público em geral, é um aplicativo de negócios que será usado em um campo de negócios muito restrito.

Na verdade, eu estava realmente ansioso para desenvolver a plataforma Android, pois ela resolve muitos problemas existentes no Windows Mobile e .NET. No entanto, a última semana foi um pouco difícil para mim ... Espero não ter que abandonar o Android, mas não parece muito bom agora = (

Existe uma maneira de eu realmente sair do aplicativo?

Ted
fonte

Respostas:

1286

Isso acabará por chegar à sua pergunta, mas primeiro quero abordar uma série de questões levantadas em seus vários comentários para as várias respostas já dadas no momento em que este artigo foi escrito. Não tenho a intenção de mudar de idéia - eles estão aqui para outros que vierem a ler este post no futuro.

O ponto é que não posso permitir que o Android determine quando meu aplicativo será encerrado. essa deve ser a escolha do usuário.

Milhões de pessoas estão perfeitamente felizes com o modelo em que o ambiente fecha o aplicativo conforme necessário. Esses usuários simplesmente não pensam em "encerrar" o aplicativo Android, assim como não pensam em "encerrar" uma página da Web ou "encerrar" um termostato.

Os usuários do iPhone são praticamente da mesma maneira, pois pressionar o botão do iPhone não necessariamente "parece" que o aplicativo foi encerrado, pois muitos aplicativos do iPhone retomam de onde o usuário parou, mesmo se o aplicativo realmente foi desligado (apenas no iPhone permite um aplicativo de terceiros por vez, no momento).

Como eu disse acima, há muitas coisas acontecendo no meu aplicativo (dados sendo enviados ao dispositivo, listas com tarefas que sempre devem estar lá etc.).

Não sei o que significa "listas com tarefas que sempre devem estar lá", mas os "dados enviados ao dispositivo" são uma ficção agradável e, de qualquer forma, não devem ser executados por uma atividade. Use uma tarefa agendada (via AlarmManager) para atualizar seus dados para obter a máxima confiabilidade.

Nossos usuários efetuam login e não podem fazer isso toda vez que recebem uma ligação e o Android decide encerrar o aplicativo.

Existem muitos aplicativos para iPhone e Android que lidam com isso. Geralmente, é porque eles mantêm credenciais de logon, em vez de forçar os usuários a efetuarem o login manualmente sempre.

Por exemplo, queremos verificar as atualizações ao sair do aplicativo

Isso é um erro em qualquer sistema operacional. Pelo que você sabe, o motivo pelo qual o aplicativo está sendo "encerrado" é porque o sistema operacional está sendo desligado e o processo de atualização falhará no meio do caminho. Geralmente, isso não é uma coisa boa. Verifique as atualizações no início ou as atualizações totalmente de forma assíncrona (por exemplo, através de uma tarefa agendada), nunca na saída.

Alguns comentários sugerem que pressionar o botão Voltar não mata o aplicativo (veja o link na minha pergunta acima).

Pressionar o botão VOLTAR não "mata o aplicativo". Finaliza a atividade que estava na tela quando o usuário pressionou o botão VOLTAR.

Ele deve terminar apenas quando os usuários quiserem terminar - nunca de qualquer outra maneira. Se você não pode escrever aplicativos que se comportam assim no Android, acho que o Android não pode ser usado para escrever aplicativos reais = (

Os aplicativos da Web também não podem. Ou WebOS , se eu entendi o modelo deles corretamente (ainda não tive a chance de brincar com um). Em todos eles, os usuários não "encerram" nada - eles simplesmente partem. O iPhone é um pouco diferente, pois atualmente só permite que uma coisa seja executada de cada vez (com algumas exceções) e, portanto, o ato de sair implica um encerramento bastante imediato do aplicativo.

Existe uma maneira de eu realmente sair do aplicativo?

Como todos os outros disseram, os usuários (via BACK) ou seu código (via finish()) podem fechar sua atividade em execução no momento. Os usuários geralmente não precisam de mais nada, para aplicativos escritos corretamente, assim como não precisam de uma opção "sair" para usar aplicativos da Web.


Não há dois ambientes de aplicativos iguais, por definição. Isso significa que você pode ver as tendências nos ambientes à medida que novas surgem e outras são enterradas.

Por exemplo, há um movimento crescente para tentar eliminar a noção de "arquivo". A maioria dos aplicativos da Web não força os usuários a pensar em arquivos. Aplicativos para iPhone normalmente não forçam os usuários a pensar em arquivos. Aplicativos Android geralmente não forçam os usuários a pensar em arquivos. E assim por diante.

Da mesma forma, há um movimento crescente para tentar eliminar a noção de "encerrar" um aplicativo. A maioria dos aplicativos da Web não força o logout do usuário, mas o encerra implicitamente após um período de inatividade. A mesma coisa acontece com o Android e, em menor grau, o iPhone (e possivelmente o WebOS).

Isso requer mais ênfase no design do aplicativo, focando nos objetivos de negócios e não aderindo a um modelo de implementação vinculado a um ambiente de aplicativo anterior. Os desenvolvedores que não tiverem tempo ou disposição para fazer isso ficarão frustrados com os ambientes mais novos que quebram seu modelo mental existente. Isso não é culpa de nenhum dos dois ambientes, assim como não é culpa de uma montanha por tempestades que fluem ao redor dela e não através dela.

Por exemplo, alguns ambientes de desenvolvimento, como Hypercard e Smalltalk, tiveram o aplicativo e as ferramentas de desenvolvimento combinadas em uma configuração. Esse conceito não pegou muito, fora das extensões de idioma dos aplicativos (por exemplo, VBA no Excel , Lisp no AutoCAD ). Os desenvolvedores que criaram modelos mentais que presumiram a existência de ferramentas de desenvolvimento no próprio aplicativo, portanto, tiveram que mudar seu modelo ou limitar-se a ambientes onde seu modelo seria verdadeiro.

Então, quando você escreve:

Juntamente com outras coisas confusas que descobri, acho que o desenvolvimento do nosso aplicativo para Android não vai acontecer.

Isso parece ser o melhor para você, por enquanto. Da mesma forma, eu aconselho você a não tentar portar seu aplicativo para a Web, já que alguns dos mesmos problemas que você relatou com o Android também encontrarão em aplicativos da Web (por exemplo, nenhuma "rescisão"). Ou, inversamente, um dia, se você fazê- port seu aplicativo para a Web, você pode achar que o fluxo do aplicativo Web pode ser um jogo melhor para o Android, e você pode revisitar uma porta Android naquele momento.

CommonsWare
fonte
21
Um pensamento surgiu na minha cabeça: se eu apenas reescrevesse o aplicativo inteiro como um Serviço e tratasse esse Serviço como o aplicativo real - talvez isso funcionasse melhor? Então, eu poderia "emburrecer" as Atividades (exatamente como o Android as deseja) para apresentar apenas os dados contidos no Serviço. Nesse caso, talvez eu pudesse manter o estado de login e outras coisas lá. Usando startForeground (int, Notification) , quase consigo parar o Android de matar o Serviço ...?
Ted
66
"Observe que meus usuários são profissionais, que usam o dispositivo com o único objetivo de usar o aplicativo que estou tentando portar para o Android." Na verdade, você indicou o contrário ("não é possível fazer isso toda vez que eles recebem uma chamada telefônica" - uma "chamada telefônica" não é o seu aplicativo). Além disso, a menos que você esteja construindo seu próprio dispositivo, não poderá impedir as pessoas de instalar outros aplicativos, se assim o desejarem.
CommonsWare
25
@SomeCallMeTim: Não, esse não é um motivo válido para usar killProcess(). É um motivo válido para escrever um código iOS melhor.
CommonsWare 30/10/10
24
@ CommmonsWare: Desculpe, mas essa é uma resposta banal que não serve para mim. Estou portando código pago para portar. Devo gastar duas vezes o tempo executando a porta, reescrevendo o código ou executá-lo da maneira que reduz os custos para o meu empregador, permitindo que eles ponham mais jogos no Android mais cedo? De qualquer forma, é uma pergunta totalmente acadêmica: eles não querem que eu faça mudanças tão importantes no mecanismo deles, já que não posso testar as alterações no iOS. E está simplesmente errado: não há nada de "ruim" em usar padrões Singleton para objetos apropriados. O Android é apenas aplicativos WRT NDK quebrados.
SomeCallMeTim 30/10/10
10
@Ted para uma reinicialização mais confiável, talvez você possa minimizar a quantidade de estado armazenada na Atividade ou no Serviço em si. Em vez disso, coloque a maior parte do estado e do código em uma classe separada que você recriará "do zero" toda vez que a Atividade ou o Serviço for iniciado.
Qwertie 17/04
290

Eu gostaria de adicionar uma correção aqui para os futuros leitores deste tópico. Essa nuance em particular escapou do meu entendimento por um longo tempo, por isso quero garantir que nenhum de vocês cometa os mesmos erros:

System.exit()não mata seu aplicativo se você tiver mais de uma atividade na pilha. O que realmente acontece é que o processo é interrompido e reiniciado imediatamente com menos uma atividade na pilha. Isso também é o que acontece quando o aplicativo é interrompido pela caixa de diálogo Forçar fechamento ou mesmo quando você tenta interromper o processo do DDMS. Este é um fato totalmente indocumentado, que eu saiba.

A resposta curta é: se você deseja sair do aplicativo, precisa acompanhar todas as atividades em sua pilha e finish()TODAS quando o usuário quiser sair (e não, não há como iterar pela pilha de atividades , você precisa gerenciar tudo isso sozinho). Mesmo isso, na verdade, não elimina o processo ou quaisquer referências pendentes que você possa ter. Simplesmente termina as atividades. Além disso, não tenho certeza se Process.killProcess(Process.myPid())funciona melhor; Eu não testei.

Se, por outro lado, não há problema em você ter atividades restantes na sua pilha, existe outro método que torna as coisas super fáceis: você Activity.moveTaskToBack(true)simplesmente embasará seu processo e exibirá a tela inicial.

A resposta longa envolve a explicação da filosofia por trás desse comportamento. A filosofia nasce de uma série de suposições:

  1. Primeiro de tudo, isso só acontece quando seu aplicativo está em primeiro plano. Se estiver em segundo plano, o processo terminará perfeitamente. No entanto, se estiver em primeiro plano, o sistema operacional assume que o usuário deseja continuar fazendo o que estava fazendo. (Se você estiver tentando matar o processo do DDMS, pressione o botão home primeiro e depois mate-o)
  2. Também assume que cada atividade é independente de todas as outras atividades. Isso geralmente acontece, por exemplo, no caso de seu aplicativo iniciar a Atividade do Navegador, que é totalmente separada e não foi escrita por você. A Atividade do Navegador pode ou não ser criada na mesma Tarefa, dependendo de seus atributos de manifesto.
  3. Ele pressupõe que cada uma de suas atividades é completamente autossuficiente e pode ser eliminada / restaurada em um momento. (Não gosto dessa suposição em particular, pois meu aplicativo tem muitas atividades que dependem de uma grande quantidade de dados em cache, grandes demais para serem serializados com eficiência durante onSaveInstanceState, mas o que farão?) Para a maioria dos aplicativos Android bem escritos, isso deve ser verdade, pois você nunca sabe quando seu aplicativo será eliminado em segundo plano.
  4. O fator final não é tanto uma suposição, mas uma limitação do sistema operacional: matar o aplicativo explicitamente é o mesmo que o aplicativo travar e também o mesmo que o Android matar o aplicativo para recuperar a memória. Isso culmina em nosso golpe de graça: como o Android não pode dizer se o aplicativo saiu ou falhou ou foi morto em segundo plano, ele pressupõe que o usuário queira retornar de onde parou e, portanto, o ActivityManager reiniciará o processo.

Quando você pensa sobre isso, isso é apropriado para a plataforma. Primeiro, é exatamente isso que acontece quando o processo é interrompido em segundo plano e o usuário volta a ele, portanto, ele precisa ser reiniciado de onde parou. Segundo, é isso que acontece quando o aplicativo falha e apresenta a temida caixa de diálogo Forçar fechamento.

Digamos que eu queira que meus usuários possam tirar uma foto e enviá-la. Inicio a Atividade da câmera a partir da minha atividade e peço que ela retorne uma imagem. A câmera é colocada na parte superior da minha tarefa atual (em vez de ser criada em sua própria tarefa). Se a câmera apresentar um erro e travar, isso deve resultar no travamento de todo o aplicativo? Do ponto de vista do usuário, apenas a Câmera falhou e eles devem retornar à atividade anterior. Portanto, ele apenas reinicia o processo com as mesmas atividades na pilha, menos a câmera. Como suas Atividades devem ser projetadas para que possam ser mortas e restauradas rapidamente, isso não deve ser um problema. Infelizmente, nem todos os aplicativos podem ser projetados dessa maneira, por isso éum problema para muitos de nós, não importa o que Romain Guy ou qualquer outra pessoa lhe diga. Portanto, precisamos usar soluções alternativas.

Então, meu último conselho:

  • Não tente matar o processo. Chame finish()todas as atividades ou ligue moveTaskToBack(true).
  • Se o seu processo travar ou morrer, e se, como eu, você precisar dos dados que estavam perdidos na memória, precisará retornar à atividade raiz. Para fazer isso, você deve chamar startActivity()com um Intent que contém o Intent.FLAG_ACTIVITY_CLEAR_TOPsinalizador.
  • Se você deseja eliminar seu aplicativo da perspectiva do DDMS do Eclipse, é melhor não estar em primeiro plano ou ele será reiniciado. Você deve pressionar o botão Início primeiro e depois matar o processo.
Neil Traft
fonte
8
Na verdade, desde que iniciei o Android novamente, estou terminando todas as atividades (apenas uma atividade está ativa a qualquer momento) e depois chamo System.exit (0); no meu serviço - e isso funciona exatamente como eu quero. Eu sei que a maioria das pessoas diz "não faça isso", mas recebo exatamente o comportamento que quero com esse movimento ...
Ted
13
Matar o processo às vezes é muito útil - por exemplo, ao escrever jogos que usam código nativo. Matar o processo significa liberar toda a memória alocada de volta ao sistema, imediatamente.
Sulthan
10
Para quem se preocupa, Process.killProcess demonstra exatamente o mesmo comportamento que System.exit ()
PacificSky
6
Derive todas as atividades de um AtivityBase comum. Em seguida, segure um sinalizador para forçar o fechamento do aplicativo; em onResume, verifique se o sinalizador de forçar fechamento está definido. Se assim for, chame System.exit (0); Isso entrará em cascata em toda a pilha de atividades e finalmente fechará o aplicativo completamente.
quer
12
Obrigado por fornecer respostas reais ( moveTaskToBack()era o que eu estava procurando). Muitas pessoas apenas dizem "Não, você é um idiota por querer sair do seu aplicativo". sem sequer considerar que pode haver casos em que você deseja (por exemplo, logins com falha).
Timmmm 26/09/12
180

Todos os meus aplicativos têm botões de encerramento ... e, com frequência, recebo comentários positivos dos usuários por causa disso. Não me importo se a plataforma foi projetada de maneira que os aplicativos não precisem deles. Dizer "não os coloque lá" é meio ridículo. Se o usuário quiser sair ... eu forneço a eles o acesso para fazer exatamente isso. Eu não acho que reduz a maneira como o Android opera e parece uma boa prática. Eu entendo o ciclo de vida ... e minha observação foi que o Android não faz um bom trabalho em lidar com isso .... e isso é um fato básico.

androidworkz
fonte
15
+1 porque infelizmente ele não faz tal bom trabalho neste ponto no tempo (mas eu ainda quero tentar fazer coisas como concebido, por isso me coloca em uma quandry)
Richard Le Mesurier
25
Que mecanismo você usa para sair?
Gary Rudolph
4
@Igor finish () - as atividades não eliminam o aplicativo (estende o Application). Portanto, mesmo quando nenhuma das atividades estava ativa, as configurações ainda estão ativas e reais, de modo que, quando as atividades tentarem acessá-las, elas serão as que foram usadas anteriormente. System.exit (0); por outro lado, mata o aplicativo, de modo que, quando iniciado novamente, o aplicativo terá que inicializar as configurações novamente. É disso que preciso ao atualizar meu aplicativo manualmente, porque frequentemente altero o formato dos dados e preciso que sejam reiniciados imediatamente.
Nar Gar
1
Bem, essa é a única maneira de realizar o que eu preciso no momento. Uso system.exit quando o aplicativo é atualizado (caso contrário, obteremos exceções de serialização ou de conversão de classe com base nas minhas alterações de código). Devo mencionar, no entanto, que eu não dou ao usuário um identificador de interface do usuário para matar o aplicativo via system.exit - ele é reservado para mim como engenheiro do aplicativo para ser usado somente quando o aplicativo precisar absolutamente descarregar completamente. O restante do tempo é utilizado um acabamento simples () (ou a operação padrão do botão voltar).
Nar Gar
13
Sim ... para o inferno com 'not android standard' .. Android é poderoso porque permite que as pessoas experimentem .. Se ele fornece APIs para fazer alguma coisa, como se pode dizer que não é o padrão Android? Não consigo digerir todas essas respostas "filosóficas". Você cria o aplicativo tendo em mente seus usuários. se eles estão felizes ou se eles querem ver esse recurso, então é absolutamente bom para implementar esse mesmo que esses chamados filósofos são contra ela ..
Rahul
144

Pare de pensar em seu aplicativo como um aplicativo monolítico. É um conjunto de telas da interface do usuário que o usuário pode interagir com seu "aplicativo" e "funções" fornecidas pelos serviços Android.

Não saber o que seu misterioso aplicativo "faz" não é realmente importante. Vamos supor que ele seja direcionado para uma intranet corporativa super segura, executando algum monitoramento ou interação e permanecendo conectado até que o usuário "saia do aplicativo". Como o departamento de TI comanda, os usuários devem estar muito conscientes de quando estão dentro ou fora da intranet. Daí a sua mentalidade de que é importante que os usuários "parem".

Isto é simples. Faça um serviço que coloque uma notificação em andamento na barra de notificação dizendo "Estou na intranet ou estou executando". Faça com que esse serviço execute todas as funcionalidades necessárias para seu aplicativo. Tenha atividades vinculadas a esse serviço para permitir que seus usuários acessem os bits da interface do usuário necessários para interagir com seu "aplicativo". E tenha um botão Menu Android -> Sair (ou sair, ou o que for) que diz ao serviço para sair e, em seguida, fecha a atividade.

Isto é, para todos os efeitos, exatamente o que você diz que deseja. Feito da maneira Android. Veja no Google Talk ou no Google Maps Navigation exemplos de "saída" dessa mentalidade possível. A única diferença é que pressionar o botão Voltar de sua atividade pode deixar seu processo UNIX em espera apenas no caso de o usuário desejar reviver seu aplicativo. Isso realmente não é diferente de um sistema operacional moderno que armazena em cache arquivos acessados ​​recentemente na memória. Depois de encerrar o programa do Windows, os recursos mais prováveis ​​necessários ainda estão na memória, aguardando para serem substituídos por outros recursos à medida que são carregados, agora que não são mais necessários. Android é a mesma coisa.

Eu realmente não vejo o seu problema.

Eric
fonte
3
@ Eric, você não o problema porque está fugindo dele. Você simplesmente utilizou outro programa que roda no antigo "modelo de programa" para fazer o que não pode ser feito pelo "modelo Android". Para ver o problema do "modelo Android", você deve imaginar que não tem o luxo de delegar tarefas às caixas Linux / Windows. Você deve imaginar que é forçado a fazer tudo, do front-end ao back-end, apenas com as caixas que executam o "modelo Android". Então, você verá que as limitações do "modelo Android" são tão claras quanto o céu.
Pacerier 17/11/14
pense no seu aplicativo como um aplicativo monolítico. Está escrito em java, que está sendo executado por um único processo JVM (Java Virtual Machine). System.exit () sai da JVM e finaliza completa e completamente todas as telas da interface do usuário e tudo mais. A exceção é se o programador tiver o problema de configurar vários threads que são executados em vários processos - mas, por padrão, esse NÃO é o caso e, de acordo com o Google, não deve ser feito normalmente.
Jesse Gordon
@JesseGordon Isso não é verdade. System.exit()remove apenas uma atividade da pilha. A JVM é imediatamente reinicializada. Veja esta resposta .
forresthopkinsa
1
@forresthopkinsa OK Eu testei no Android 7.0. Um aplicativo encadeado único simples ainda é executado em sua própria instância JVM dedicada, sendo executado como um ID do usuário exclusivo para esse aplicativo. Ainda não experimentei uma aplicação multithread para este teste. E System.exit () AINDA mata toda a JVM para esse aplicativo. Se o System.exit () for chamado a partir da atividade principal, ele será encerrado. Se System.exit () for chamado a partir de uma subatividade, a JVM ainda será eliminada, mas o Android o reinicia com um novo ID de processo na atividade principal / primeira. android.os.Process.killProcess (android.os.Process.myPid ()); e matar <pid> funcionam da mesma maneira.
Jesse Gordon
1
Interessante .. Examinando a resposta que você vinculou, @forresthopkinsa, parece que o Android está funcionando como navegadores da web, restaurando as atividades após um system.exit para que o usuário não perceba que ele saiu, mas excluindo a atividade que causou a saída. .? Esquisito. Mas de qualquer maneira, System.exit () faz perto todas as atividades e free () é a memória e termina a JVM para essa aplicação. Mas não tenho idéia de que tipo de brincadeira o Android faz para reiniciá-lo / restaurá-lo. É para frustrar aplicativos assassinos de aplicativos? Então, acho que se alguém quiser um botão de saída, deve colocá-lo na atividade principal.
Jesse Gordon
71

Esta é uma discussão interessante e perspicaz com tantos especialistas contribuindo. Eu acho que este post deve voltar do site principal de desenvolvimento do Android, porque gira em torno de um dos principais designs do sistema operacional Android.

Eu também gostaria de adicionar meus dois centavos aqui.

Até agora, fiquei impressionado com a maneira como o Android lida com eventos do ciclo de vida, trazendo o conceito de uma experiência da Web para aplicativos nativos.

Dito isto, ainda acredito que deve haver um Quitbotão. Por quê? ... não para mim, Ted ou qualquer um dos gurus da tecnologia aqui, mas com o único objetivo de atender a uma demanda do usuário final.

Embora eu não seja um grande fã do Windows, mas há muito tempo eles introduziram um conceito ao qual a maioria dos usuários finais está acostumada (um botão X) ... "Quero parar de executar um widget quando 'eu' quiser".

Isso não significa que alguém (SO, desenvolvedor?) Cuidará disso a seu próprio critério ... significa simplesmente "onde está meu botão X vermelho com o qual estou acostumado". Minha ação deve ser análoga a "encerrar uma ligação ao pressionar um botão", "desligar o dispositivo pressionando um botão" e assim por diante ... é uma percepção. Traz uma satisfação per se que minha ação realmente alcance seu objetivo.

Mesmo que um desenvolvedor possa falsificar esse comportamento usando as sugestões fornecidas aqui, a percepção ainda permanece, ou seja, um aplicativo deve deixar de funcionar completamente (agora), por uma fonte independente, confiável e neutra (SO) sob demanda do usuário final.

Paul
fonte
2
Direita. O bom e velho Windows Mobile ofereceu o mesmo botão X que os PCs com Windows, exceto que ele realmente não saiu do aplicativo, apenas o "minimizou de forma inteligente". Muitos usuários provavelmente nunca descobriram que o aplicativo realmente não saiu. (A abordagem funcionou muito bem, mas se você usou .NET Compact Framework, o aplicativo não foi notificado de que isso tinha acontecido e por isso não tem a opção de recursos livres ou realmente sair.)
Qwertie
3
Realmente, isso equivale a mentir para os usuários para proporcionar uma sensação de aconchego e distorção. Por fim, é melhor deixar as relíquias do passado desmoronar, para que não continuem sendo dispositivos permanentes de tecnologia. Dispositivos móveis e web são novas plataformas e não se espera que se comportem da mesma maneira que computadores. E, anedoticamente, pelo menos, as decisões do ciclo de vida do Android parecem estar pegando os usuários: quando meu maior aplicativo passa dois anos, percebi o fluxo de solicitações do usuário final por botões de "saída" secando à medida que se acostumam com o nova plataforma.
30812 Jon O
2
@ Jon O que você recomenda? Não está oferecendo uma opção de 'saída' em qualquer lugar do aplicativo?
IgorGanapolsky
Bem, quando um usuário solicitava um botão de saída, eu explicaria a eles exatamente como as coisas funcionavam de maneira diferente do que em uma área de trabalho (que é a mesma explicação que eu dou a eles quando mencionam matadores de tarefas). Agora, as informações parecem ter pego, e eu não recebo mais esses pedidos. Portanto, recomendo que você o explique algumas vezes (talvez tenha uma resposta em lata) e deixe de fora o botão. Ou coloque um botão de saída falso que abre uma caixa de diálogo explicando por que não há mais botões de saída. : D (também no Android 4+, um usuário pode deslizar um aplicativo para fora da tela multitarefa para "matá-lo").
Jon O
3
Também não encontrei o raciocínio por trás de todos os conselhos dizendo "não mate o processo". Na minha opinião, o cliente está sempre certo, então o que há de errado em fornecer um botão de saída depois que ele foi solicitado e "mentir para os usuários para lhes dar uma sensação acolhedora e confusa", se é isso que eles querem? Isso é em parte o objetivo de escrever bons aplicativos. A maioria dos usuários não sabe ou se importa com o que realmente está acontecendo, mas se eles gostam do seu aplicativo e fazem o que querem e esperam, voltam e compram mais aplicativos. É isso que todos queremos, não é? Ou eu estou esquecendo de alguma coisa?
DDSports
37

Você pode sair pressionando o Backbotão ou ligando finish()para o seu Activity. Basta ligar finish()de a MenuItemse você quiser eliminá-lo explicitamente.

A Romain não está dizendo que isso não pode ser feito, apenas que é inútil - os usuários não precisam se preocupar em parar ou salvar seu trabalho ou o que quer que seja, pois a maneira como o ciclo de vida do aplicativo funciona incentiva você a escrever um software inteligente que salve e restaura seu estado, não importa o que aconteça.

Christopher Orr
fonte
5
Não faz sentido se ele cumpre um propósito, e em nossa aplicação ele faz exatamente isso. Por exemplo, queremos verificar as atualizações ao sair do aplicativo. Não podemos sair do aplicativo, então nenhuma atualização pode ser feita. Alguns comentários sugerem que pressionar o botão Voltar não mata o aplicativo (veja o link na minha pergunta acima).
Ted
2
Como Romain diz, não é assim que os aplicativos principais funcionam. Portanto, se os usuários estão acostumados a pressionar "Voltar" para sair de um aplicativo, parece provável que eles continuem a fazê-lo com seu aplicativo, em vez de escolher explicitamente Sair? Você pode fazer uma verificação de atualização na inicialização, no onDestroy () ou usando um alarme repetido. Não parece ser algo que precise ser acionado por um usuário.
Christopher Orr
1
Tom: Eu tenho codificado para Windows Mobile há quase 5 anos. É um telefone com "recursos limitados". Não existe esse comportamento lá, e não há problemas que ele não atue nesse "irmão mais velho" - também. "Aplicativos reais" = onde o programador tem muito mais controle sobre ele, ou seja, parar de fumar, quando GUI-stuff é removido etc ...
Ted
1
Jay: porque se ainda está na memória, não consigo atualizar o aplicativo que estou pensando. Não é possível excluir arquivos que estão em uso, certo? Quero atualizar na saída porque não podemos forçar nossos usuários a atualizar no início. Isso tem a ver com como eles funcionam e com o que precisam. Não é aceitável que eles sejam forçados a atualizar no início de seu turno por diferentes motivos. É um pouco complicado.
Ted
1
Jay: Não, como afirmei a respeito, NÃO é um aplicativo de mercado e também não será esse. É um aplicativo muito especializado, não para uso geral.
Ted
31

Esse debate se resume à antiga questão de saber se os desenvolvedores sabem melhor ou se o usuário sabe melhor. Designers profissionais em todas as áreas de fatores humanos lutam com isso todos os dias.

Ted fez questão de afirmar que um dos aplicativos mais baixados no mercado é o 'App Killer'. As pessoas recebem um pouco de serotonina extra ao sair dos aplicativos. Eles estão acostumados a isso com um desktop / laptop. Mantém as coisas em movimento rápido. Mantém o processador frio e o ventilador ligado. Ele usa menos energia.

Quando você considera que um dispositivo móvel é um navio muito menor, pode apreciar especialmente o incentivo deles para "lançar ao mar o que não é mais necessário". Agora, os desenvolvedores do Android argumentaram que o sistema operacional sabe melhor e que sair de um aplicativo é antigo. Eu sinceramente apoio isso.

No entanto, também acredito que você não deve frustrar o usuário, mesmo que essa frustração seja causada por sua própria ignorância. Por esse motivo, concluo que ter uma opção 'Sair' é um bom design, mesmo que seja principalmente um botão de placebo que não faz nada além de fechar uma Visualização.

Peter Mortensen
fonte
8
Sim, ter um botão 'Sair' é realmente fácil de usar. De que outra forma o usuário sairia do aplicativo se ele estivesse com cinco atividades profundas? Claro que eles podem pressionar várias vezes, mas não acho que eles gostariam disso.
IgorGanapolsky 12/09/12
4
Apenas 5? O navegador da Web Android 2.2 me faz gastar alguns minutos pressionando o botão de voltar até que eu saia
Joe Plante
3
Gostaria de começar a ouvir os desenvolvedores do Android quando eles desenvolvem o gerenciador de memória que FUNCIONA. No Froyo, ele funcionou muito mal, eliminando aplicativos aleatórios, reiniciando aplicativos que não precisam ser (e não têm intenção de iniciá-los legitimamente) e o OTOH, diminuindo para um rastreamento COMPLETO quando a memória atinge 50 MB livres.
DVK
10
Quando sua religião diz que o Android Task Killer é "desnecessário", mas o uso do ATK para eliminar tarefas idiotas que não têm negócios em andamento faz com que o sistema operacional rastreie a ~ 1-5% da velocidade normal e volte a 100% da velocidade normal ( medido) de 100% do tempo através de 1000s de usos ATK mais de 2 anos cada vez que os hits do sistema 50MB livre low end, a sua religião é errado
DVK
@ JoePlante Você pode fechar todas as abas e janelas abertas primeiro e simplesmente pressionar o botão Voltar uma vez para sair :) Pelo menos no meu GS2.
Ld #
29

Ted, o que você está tentando realizar pode ser feito, talvez não apenas como você está pensando nisso agora.

Eu sugiro que você leia sobre Atividades e serviços. Pare de usar o termo "aplicativo" e comece a se referir aos componentes, ou seja, Atividade, Serviço. Eu acho que você só precisa aprender mais sobre a plataforma Android; é uma mudança de mentalidade de um aplicativo para PC padrão. O fato de nenhuma das suas postagens ter a palavra "Atividade" (exceto uma citação na FAQ, ou seja, não as suas palavras) nelas me diz que você precisa ler um pouco mais.

Peter Mortensen
fonte
Eu li a maioria das coisas em android.com =) e posso fazer o link para várias perguntas em que falo sobre Atividades, então isso não é verdade (por exemplo: stackoverflow.com/questions/2032335/… ou stackoverflow.com/questions/ 2032335 / ... etc ...) no entanto, eu poderia dar-lhe uma última vez, e tentar criar o "app" que como um serviço sofreu com isso ...
Ted
4
Um aplicativo pode conter serviços e atividades e parece que seu aplicativo pode precisar de ambos. A atividade é apenas a parte da interface do usuário.
Aaron
23

Postagem no blog Quando incluir um botão Sair nos aplicativos Android (Dica: nunca) explica muito, muito melhor do que eu. Desejo que todos os desenvolvedores do Android já tenham lido.

Trechos:

Na minha experiência, o que [os usuários] realmente querem é: Uma maneira inequívoca de garantir que um aplicativo pare de consumir recursos (bateria, ciclos de CPU, transferência de dados etc.).

Muitos usuários percebem que um botão de saída implementa esse requisito e solicitam que ele seja adicionado. Os desenvolvedores, procurando agradar seus usuários, adicionam obrigatoriamente um. Pouco tempo depois, ambos falham.

  • Na maioria dos casos, o botão de saída simplesmente chama Activity.finish(). Isso é exatamente equivalente a pressionar o botão Voltar. Exatamente. Os serviços continuam funcionando e as pesquisas continuam acontecendo. Os usuários podem pensar que mataram o aplicativo, mas não o mataram, e logo ficarão ainda mais irritados.
  • O comportamento de saída agora é ambíguo. O botão de saída deve fechar a atividade ou também parar todos os serviços, receptores e alarmes associados? O que deve Backfazer? O que acontece se eles acertarem Home? O que acontece se o seu aplicativo tiver um widget? O botão de saída também deve impedir a atualização?

A solução é fazer com que o botão voltar se comporte como seria de esperar do botão sair. Melhor ainda, simplesmente pare de consumir recursos sempre que o aplicativo não estiver visível.

Vá em frente e leia o artigo completo.

Dheeraj VS
fonte
3
Sair e Voltar nem sempre são usados ​​para a mesma finalidade. Tome, por exemplo, Pandora. Quando você pressiona para sair deste aplicativo, ele não sai do aplicativo (mantém-o em segundo plano como um serviço).
IgorGanapolsky
@IgorG. Um aplicativo de player de música precisa de um botão "Parar" para interromper a reprodução de música, não de um botão "Sair" para sair do aplicativo.
Dheeraj Vepakomma
Você já usou Pandora, iHeartRadio, Spotify, Jango e outros aplicativos de streaming de música? Todos eles têm um botão de sair. Interromper a reprodução de música NÃO É A MESMA COISA como sair de um aplicativo. Especialmente se você tiver um serviço em execução na barra de notificação.
IgorGanapolsky
2
Mítico ou não, usuários primitivos ou não, mas quase todos os softwares de interface do usuário já escritos - em qualquer plataforma e sistema operacional - implementam um botão Sair / Fechar / Sair. De que outra forma você o implementaria?
IgorGanapolsky
3
@ DheerajV.S., Basta parar de consumir recursos sempre que o aplicativo não estiver visível? Mau conselho. Muito. Muito x99. Sempre que tento me enviar uma foto por e-mail, tenho que manter o aplicativo visível por 5 minutos, porque, se minimizá-lo, ele pára de enviar a foto. Correto, não consigo usar meu telefone por 5 minutos apenas por causa de algum desenvolvedor que acha que os aplicativos devem ser executados somente quando visíveis. Agora imagine o envio de um arquivo maior, como vídeo .....
Pacerier
21

Resposta: (Romain Guy): O usuário não, o sistema lida com isso automaticamente. É para isso que serve o ciclo de vida da atividade (especialmente onPause / onStop / onDestroy). Não importa o que você faça, não coloque um botão de aplicativo "sair" ou "sair". É inútil com o modelo de aplicativo do Android. Isso também é contrário ao funcionamento dos aplicativos principais.

1: Sair totalmente de um aplicativo pode geralmente não ser obrigatório, mas não é inútil. E se o Windows não tivesse opção de saída? O sistema ficaria devagar, pois a memória estava cheia e o sistema operacional precisava adivinhar em quais programas você terminava. Não me importo com o que Romain Guy ou mesmo Larry Page e Sergey Brin dizem - estes são fatos inquestionáveis: os sistemas ficam mais lentos quando precisam matar tarefas para recuperar a memória antes que um novo aplicativo possa ser lançado. Você simplesmente não pode me dizer que não leva tempo para matar um aplicativo! Mesmo a luz de estrelas distantes levar tempo ... Não é alguma utilidade em permitir que o usuário para aplicativos totalmente íntimos.

2: Ao contrário de como os aplicativos principais funcionam? O que isso deveria significar? Quando terminei de executar um aplicativo por enquanto, ele não está mais funcionando ... Está apenas esperando para ser morto pelo sistema operacional quando sua memória for necessária.

Em resumo, há uma diferença distinta entre minimizar e sair, e nenhuma pitada atinge bem o outro. Deixamos uma chave de fenda em cada parafuso? Ou uma chave em cada porta? Deixamos todos os nossos aparelhos no alto até o disjuntor explodir e precisamos ligar outro aparelho? Deixamos a lavadora de pratos cheia de louça e retiramos o suficiente a cada vez para dar espaço a algumas sujas novas? Deixamos todos os carros na garagem até - oh, não importa.

Se o usuário deseja minimizar um aplicativo, o melhor é minimizá-lo. Se um usuário quiser sair de um aplicativo, é melhor sair.

É desaprovado? Essa é a visão do Android - eles fazem uma careta. E muitos desenvolvedores estreantes independentes do Android desaprovam isso.

Mas quando se trata disso, há boas e más codificações. Existem bons modelos de fluxo de programa e existem modelos de fluxo de programa ruins.

Deixar programas na memória quando o usuário sabe que eles acabaram com eles simplesmente não é um bom fluxo de programas. Ele não tem absolutamente nenhum propósito e diminui a velocidade ao iniciar novos aplicativos ou ao executar aplicativos alocam mais memória.

É como o seu carro: há momentos em que você o deixa em funcionamento, como parar em um semáforo, ou talvez o fast food passe ou pare no caixa eletrônico. Mas há outras situações em que você deseja desligá-lo - como quando chega ao trabalho, ao supermercado ou até em casa.

Da mesma forma, se você estiver jogando e o telefone tocar, sim. Pause o jogo e mantenha-o funcionando. Mas se o usuário terminar o jogo por um tempo, então deixe-o sair.

O botão de saída em alguns aplicativos deve estar mais na frente do que outros. Jogos, por exemplo, ou programas em que o usuário provavelmente deseja sair completamente, deve ter uma saída óbvia. Outros programas, como, talvez, programas de e-mail, em que sair é um desejo improvável (para que ele possa continuar checando por e-mail) - esses programas não devem desperdiçar espaço na tela de entrada de controle principal com uma opção de saída, mas, para um bom fluxo de programa, deve ter uma opção de saída. E se alguém decidir que não quer que seu programa de e-mail tente verificar o e-mail quando estiver em uma área de baixa cobertura, ou talvez em uma chamada do Skype ou o que seja? Deixe-os sair do programa de email, se quiserem!

Suspender e sair são duas tarefas vitais e nenhuma delas cumpre o papel da outra.

Jesse Gordon
fonte
2
"Se o usuário deseja minimizar um aplicativo, o melhor é minimizá-lo. Se um usuário deseja sair de um aplicativo, é melhor que saia." - Há uma coisa (com base em mais de uma década de experiência): os usuários raramente sabem o que querem. Se você não os ajudar, precisará alterá-lo. Sobre as amostras acima: deixe-me dar outra amostra: você está trabalhando em um carro e tem uma mesa à mão para as coisas. Você sempre guarda para colocar todas as ferramentas necessárias no armário ou manter as ferramentas mais usadas à mão? E guardar um grande atraso usado para ter lugar para novos?
HoGo 02/02
4
HoGo, obrigado pelo seu comentário. Naturalmente, eu discordo. Especificamente, da melhor maneira que posso dizer, sua opinião é que, como alguns usuários não sabem o que devem fazer, não deixam nenhum usuário fazer o que devem fazer, nem mesmo aqueles que sabem o que devem fazer. Se o Android tiver uma maneira de saber com precisão se deve encerrar um aplicativo em vez de minimizá-lo, tudo bem. Mas isso não acontece, e forçar todos os usuários a viver sempre com minimização quando desejam sair leva a um desempenho ruim do dispositivo.
Jesse Gordon
O problema é que o sistema sabe que quando você inicia um aplicativo e não há memória, ele deve matar o último. O usuário não deveria saber disso. Você só quer isso porque é um humano que gosta de sentir o controle, é apenas uma memória muscular estúpida, é mesmo um controle inútil ter que fechar programas. Os computadores foram inventados para automatizar, eu gostaria que o Windows funcionasse como o Android e fechasse automaticamente para mim, mas preciso me lembrar de salvar e sair, isso é bobagem, por que devo fazer isso? computadores devem gerenciar sua memória, tenho outras coisas para gerenciar.
Luiz Felipe
Na verdade, não fecho programas na minha máquina Windows, tenho 32 GB de RAM, deixo tudo em execução, fecho-os quando termino o trabalho. Por que fechar o programa, para abri-lo novamente 5 minutos depois, isso não faz sentido. Pense em um grande projeto C ++ que leva 2 minutos para se tornar responsivo, deixo o Visual Studio aberto para sempre. E eu espero que também não falhe após 15 dias de abertura (e sim, eu uso a memória ECC para isso).
Luiz Felipe
A analogia com a oficina é boa, também deixo as ferramentas mais usadas em cima da minha mesa, não escolho a ferramenta, a uso e a coloco de volta sempre. Além disso, não começo o dia, ligo o computador, aguardo o início, abra o IDE, o que seja. Acabei de deixá-lo em execução, o computador moderno pode ocioso em 40w, por que fechar? também usa menos os componentes (sem corrente de irrupção, os EEs sabem disso :))
Luiz Felipe
19

Acho que o ponto é que não há necessidade de sair do aplicativo, a menos que você tenha um software de buggy. O Android sai do aplicativo quando o usuário não o está usando e o dispositivo precisa de mais memória. Se você tiver um aplicativo que precise executar um serviço em segundo plano, provavelmente desejará uma maneira de desativar o serviço.

Por exemplo, o Google Listen continua a reproduzir podcast quando o aplicativo não está visível. Mas sempre há o botão de pausa para desativar o podcast quando o usuário termina. Se bem me lembro, ouça, até coloca um atalho na barra de notificação para que você possa sempre acessar o botão de pausa rapidamente. Outro exemplo é um aplicativo como o Twitter, por exemplo, que pesquisa constantemente um serviço na Internet. Esses tipos de aplicativos realmente devem permitir que o usuário escolha com que frequência pesquisar no servidor ou se deseja pesquisar em um encadeamento em segundo plano.

Se você precisar ter um código que seja executado na saída, poderá substituir onPause (), onStop () ou onDestroy () conforme apropriado. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Jay Askren
fonte
5
Juntamente com outras coisas confusas que descobri, acho que o desenvolvimento do nosso aplicativo para Android não vai acontecer. É muita coisa "big brother" acontecendo, onde o Android me diz qual aplicativo deve estar em execução ou não. Eu, como programador, deveria ter essa opção, não o google ou o android = (
Ted
3
Suas atividades - a interface do usuário ativa - desaparecem quando outro aplicativo é ativado, ou você pressiona a tecla Voltar ou o que for. O usuário não está interagindo com eles, portanto, é mais seguro salvar o estado, caso o usuário não volte por muito tempo, e assim por diante, como você sabe. Não há nada que impeça você de escrever um Servicepensamento para manter o trabalho em andamento em segundo plano, como receber push de dados ou o que for. O Google Talk não para de funcionar quando você está usando um aplicativo diferente. O mesmo com o Music player. Veja os outros aplicativos por aí e como eles funcionam.
Christopher Orr
3
Você deve salvar as credenciais para que os usuários não precisem fazer login sempre que receberem uma ligação ou se afastarem do aplicativo. Eu recomendaria analisar o ciclo de vida do Android. Quando o aplicativo é pausado, parado ou destruído, você pode salvar todos os dados relevantes para que, quando o aplicativo for aberto novamente, seja como eles o deixaram. O usuário nem precisa saber que o aplicativo já foi parado.
Jay Askren
1
Eu posso imaginar que um usuário pode querer sair de alguns aplicativos realmente intensivos em recursos. Talvez ele deve apenas reduzir seu uso de recursos quando se está em pausa, mas isso pode não ser sempre possível
Casebash
1
Ainda estou vendo essas perguntas, 4 anos depois de a ter levantado =) Na verdade, eu a executei como um serviço em segundo plano, mas adicionei o botão Quit, pois ainda sinto - 4 anos depois - que é necessário e importante. E vejo mais e mais aplicativos que possuem isso também (Skype, por exemplo).
Ted
19

Se você não conseguir entender como tornar seus dados / conexões (e, portanto, seu "aplicativo") persistentes, não poderá fazer o que "precisa" de fazer com o Android.

Aqueles que fazem o download desses pequenos assassinos de aplicativos geralmente acham que não ajudam a vida da bateria ou o uso da memória, mas impedem o sistema operacional de fazer seu trabalho de gerenciar a memória com eficiência ...

http://android-developers.blogspot.com/2010/04/multitasking-android-way.html

Dan
fonte
Enquanto falamos sobre assassinos de tarefas, um post muito esclarecedor apareceu no reddit do Android há alguns dias. A essência é, assassinos tarefa uso com cuidado ou você realmente pode acabar prejudicando a sua vida útil da bateria: reddit.com/r/Android/comments/cwhm6/...
Neil Traft
@ Neil Traft, achei os comentários no post muito esclarecedores. Os representantes de vendas nas lojas estão recomendando e instalar assassinos tarefa para seus clientes :)
dipu
3
@ Dan, como é possível, remotamente, que eu saia completamente de um aplicativo que eu terminei por uma semana, impedindo o sistema operacional Android de seu trabalho? Portanto, há mais memória livre. Isso não pode impedir o android! Mas certamente poderia acelerar as coisas mais tarde! Se eu sei que terminei com o aplicativo por um tempo, ele não serve para nada. Leva apenas memória e, mais cedo ou mais tarde, lançarei um novo aplicativo e o sistema operacional terá um atraso adicional, pois ele precisará matar alguns aplicativos que eu conhecia há SEMANAS atrás que eu havia terminado.
precisa saber é o seguinte
@ Jessie Gordon, você assistiu aos processos reais depois de matar um aplicativo? Eles são reiniciados, o sistema operacional assume que houve um problema ... O sistema operacional matará os aplicativos quando precisar de memória. Você leu alguma coisa postada nos artigos mencionados por aqui?
Dan
@ Dan, ao pensar que o Android faria algo assim ... ele realmente precisa de uma séria reeducação sobre lavagem de branco.
Pacerier
18

Eu consideraria ler "Android Wireless Application Development" publicado pela Addison-Wesley. Estou apenas terminando e é MUITO minucioso.

Parece que você tem alguns mal-entendidos fundamentais da plataforma Android. Também fiquei um pouco frustrado no início com o ciclo de vida dos aplicativos para Android, mas depois de chegar a um entendimento maior, passei a gostar realmente dessa abordagem. Este livro responderá a todas as suas perguntas e muito mais. É realmente o melhor recurso que encontrei para novos desenvolvedores do Android.

Além disso, acho que você precisa liberar uma porta linha por linha do aplicativo existente. Para portar seu aplicativo para a plataforma Android, parte do design do aplicativo será alterado. O ciclo de vida do aplicativo usado é necessário, pois os dispositivos móveis têm recursos muito limitados em relação aos sistemas de desktop e permitem que os dispositivos Android executem vários aplicativos de maneira ordenada e com reconhecimento de recursos. Faça um estudo mais aprofundado da plataforma, e acho que você perceberá que o que você quer fazer é inteiramente viável. Boa sorte.

A propósito, não sou afiliado à Addison-Wesley ou a qualquer pessoa ou organização associada a este livro. Depois de reler o meu post, sinto que fiquei um pouco fanboy. Eu realmente gostei muito e achei extremamente útil. :)

Peter Mortensen
fonte
2
Obrigado pela dica do livro. Vou dar uma olhada, se eu puder e se decidir mudar para a porta Android. Apenas para dizer novamente: nossos usuários não estão muito atualizados quando se trata de computadores. Ficarei muito difícil para eles usarem, por exemplo, o NotificationBar no Android. Muito pequeno (eles têm grandes dedos hehe). É um mundo diferente para eles, por isso precisamos mantê-lo simples e sem opções para o usuário. Nós construímos a nossa .NET solução com isso em mente - não dar-lhes uma escolha =)
Ted
Eu ouvi isso. Você deve assumir que a maioria dos usuários não é muito inteligente em termos de tecnologia.
Andy
8
Fico tão cansado do mantra de quão poucos "recursos" um dispositivo móvel possui. Acorde, eles estão funcionando com mais de 500 MHz e tem muita memória. Meu antigo Dell Axim tinha 128 MB de RAM. Os dispositivos atuais por aí geralmente têm mais de 512RAM e rodam em 1GHZ! Isso é 10 vezes mais do que meu antigo Pentium 90Mhz, e eu não ouvi pessoas dizendo "os recursos muito limitados" isso e aquilo. É hora de acordar e cheirar o café - estamos em 2010 agora, não nos anos 80.
Ted
16

Quase 99% do tempo, não há necessidade de um aplicativo Android assumir seu próprio ciclo de vida. Na maioria das vezes, tudo se resume a um melhor planejamento ou design mais inteligente do aplicativo. Por exemplo, crie um serviço interno (não exportado) para lidar com downloads etc. ou crie ações e tarefas em torno do fluxo de trabalho do usuário.

Mas dito isso, onde há vontade, há um caminho. O Android fornece - por meio da classe android.os.Process, uma API muito melhor que Java para controlar o processo subjacente. E, diferentemente do Java, ele não trata o desenvolvedor como um idiota, ocultando tudo por trás de uma simples chamada java.lang.System.exit ().

Então, como você pede ao seu aplicativo para se suicidar no Android? Bem, o truque é simples:

Crie sua própria classe de aplicativo Android, herdando da classe padrão android.app.Application (lembre-se de declará-la no arquivo AndroidManifest.xml).

Substitua o método onCreate () e armazene o ID do processo que iniciou seu aplicativo:

this.pid = android.os.Process.myPid(); // Save for later use.

Agora, para matar seu aplicativo, forneça um método kill ():

android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL);

Agora, sempre que você precisar que seu aplicativo cometa suicídio, basta digitar o contexto do aplicativo e chamar seu método de matar!

((MySuicidalApp) context.getApplicationContext()).kill()

Lembre-se de que, devido às políticas de gerenciamento de processos no Android, especificamente relacionadas aos serviços, o Android pode optar por reiniciar o serviço (consulte Você não deve usar assassinos de tarefas no Android ).

Andries
fonte
sim, eu só vim aqui porque queria fechar meu aplicativo em uma situação que faz sentido, meu cache de dados OBB está corrompido e preciso reiniciar o aplicativo inteiro
Luiz Felipe
14

Quando concebo um aplicativo no Android, vejo o seguinte:

  • Você está trabalhando com seu aplicativo
  • O telefone tocou
  • Você atende
  • No final da ligação, você volta ao seu aplicativo no mesmo local em que estava

Para fazer isso, você só precisa do Backbotão ou do Homebotão do telefone (pressionando rapidamente ou demoradamente) e a barra de notificação.

Quando Backsaio do aplicativo, só uso o botão até sair dele ou o Homebotão.

É assim que a maioria das aplicações é concebida, eu acho. Mas se eu precisar de algum tipo de sessão ou conexão, deixei claro para o usuário com um botão de login / logout e uma notificação (barra de título ou qualquer outra coisa). Esse é um estilo bastante diferente do aplicativo de estilo "saída" puro.

Nos PCs, você tem uma área de trabalho com várias GUIs e, no Android, obviamente, possui várias tarefas, mas só exibe um aplicativo por vez (não considero widgets aqui ^^). E em um telefone celular, a qualquer momento, você pode receber uma notificação sobre algo mais importante do que o que está fazendo.

Portanto, todo o conceito de um aplicativo depende de algo diferente que "entre no aplicativo - trabalhe - saia do aplicativo".

Solostaran14
fonte
12

Hmmmm ...

Eu acho que você simplesmente não vê o aplicativo Android da maneira certa. Você pode fazer algo quase como o que deseja facilmente:

  • As atividades do aplicativo salvam / restauram o estado como é incentivado na documentação do ciclo de vida do desenvolvedor.

  • Se algum login for necessário no estágio de restauração (nenhuma informação de login / sessão disponível), faça-o.

  • Eventualmente, adicione um botão / menu / tempo limite; nesse caso, você fará isso finish()sem salvar o login e outras informações da sessão, tornando implicitamente o fim da sessão do aplicativo: portanto, se o aplicativo for iniciado / trazido para a frente novamente, iniciará uma nova sessão.

Dessa forma, você realmente não se importa se o aplicativo é realmente removido da memória ou não.

Se você realmente quiser removê-lo da memória (isto é desencorajado, e BTW para quê?), Você pode matá-lo condicionalmente no final onDestroy()com java.lang.System.exit(0)(ou talvez restartPackage(..)?). Obviamente, faça isso apenas no caso em que você deseja "realmente finalizar o aplicativo", porque isso onDestroy()faz parte do ciclo de vida normal das atividades e não é um fim do aplicativo.

Slig
fonte
11

Como um Aplicativo em um contexto Android é apenas um monte de Atividades vagamente relacionadas, sair de um Aplicativo não faz muito sentido. Você pode finalizar () uma atividade, e a visualização da atividade anterior na pilha de atividades será desenhada.

Ao Sr
fonte
2
Sair de um aplicativo certamente pode fazer sentido em algumas situações. Se for um programa que você usa algumas vezes por mês por alguns minutos, há um benefício inquestionável em sair totalmente do aplicativo. Esse benefício é que o sistema operacional não precisará reservar um tempo para sair do aplicativo uma semana depois, quando a memória estiver insuficiente e o telefone tocar e você pressionar o botão de resposta, e você estará esperando o Android liberar alguma memória para que você possa atender sua ligação, por exemplo. Ou talvez você tenha um e-mail e queira lê-lo - qualquer aplicativo que precise de mais memória será iniciado mais rapidamente se o sistema operacional não o liberar primeiro.
precisa saber é o seguinte
3
O que o @JesseGordon disse, e outro aspecto desse motivo pelo qual desistir faz sentido: se eu não sair desse aplicativo com muitos recursos, sei que não vou usar novamente por um mês, o sistema operacional às vezes mata erroneamente outro aplicativo quando os recursos ficam escassos, ao mesmo tempo em que deixa esse aplicativo inútil de recursos em execução ... tornando o outro aplicativo mais demorado do que deveria.
Don escotilha
10

Eu concordo com o Ted. Entendo que sair do aplicativo não é o "caminho do Android", mas não parece que deva ser impedido. Aqui estão três razões pelas quais você pode querer uma saída real para o aplicativo (não apenas a atividade):

  1. O usuário pode querer algum controle sobre qual aplicativo é morto no caso de pouca memória. Se o aplicativo A importante estiver em execução em segundo plano, convém sair do aplicativo B quando terminar, para que o aplicativo A não seja morto pelo sistema operacional.

  2. Se o seu aplicativo tiver dados confidenciais armazenados em cache na memória, convém interromper o aplicativo para que um aplicativo antivírus / worm / desonesto não o consiga. Eu sei que o modelo de segurança deve impedir isso, mas por precaução ...

  3. Se seu aplicativo usa recursos (como rede, CPU, sensores etc.) que podem afetar adversamente o telefone, uma maneira de garantir que esses recursos sejam liberados é sair do aplicativo. Entendo que aplicativos bem comportados devem liberar recursos quando não forem necessários. Mas, novamente, sair do aplicativo parece ser uma maneira razoável de garantir isso.

Burke
fonte
6
O que você acha que representa o "aplicativo"? Se eu abrir o aplicativo do Facebook e definir uma nova foto de perfil - meus aplicativos de Câmera ou Galeria serão inicializados. Como usuário, ainda estou executando a mesma tarefa (usando o Facebook). Se eu decidir fechar o Facebook, meus aplicativos de Câmera e Galeria também deverão ser fechados (já que são atividades iniciadas no Facebook) ... E se eu estivesse no meio da edição de algumas das minhas outras fotos e tivesse apenas a intenção de fechar o Facebook ? Você teria mudado o problema para uma potencial perda de dados.
Seanhodges
Bem, eu não acho que poderia ir tão longe quanto a perda de dados. Se você possui uma atividade de terceiros em execução na mesma tarefa que a sua própria atividade, e essa é a que possui o botão de saída, o usuário deve fazer finish()a atividade de terceiros antes que ele possa pressionar o botão de saída. E a atividade de terceiros deve salvar as informações não salvas naquele momento. Não acho que você possa usar o alternador de aplicativos para retornar à atividade do botão de saída, a menos que esteja executando uma tarefa separada. E se for uma tarefa separada, é um processo separado e, portanto, não será eliminado pelo botão sair.
Neil Traft
2
1. Acho que 99,99% dos usuários do Android não devem se preocupar com o modo como o sistema operacional gerencia os aplicativos por trás das cortinas. O restante são geeks e encontrará ferramentas avançadas que fazem o sistema se comportar exatamente como eles querem. 2. Você sempre pode descarregar quaisquer dados confidenciais quando a atividade for pausada ou parada. 3. Assim como acima, os recursos podem ser liberados nos métodos de retorno de chamada do ciclo de vida. Quando a atividade é retomada, os recursos podem ser alocados novamente.
Zsolt Török
4
Eu acho que é bastante interessante que tantos usuários do Android estejam instalando o "Advanced Task Killer", um aplicativo que fecha outros aplicativos, já que você normalmente não pode fazer isso sozinho. Eu uso o tempo todo sozinho. Sair de um aplicativo não é algo que eu sinto que você pode prescindir.
Ted
2
@ ZsoltTörök, 99,99% das pessoas lidam com computadores / telefones lentos e são forçadas a optar por se preocupar com a maneira como o sistema operacional gerencia aplicativos por trás das cortinas.
Pacerier
10

O kernel do Linux possui um recurso chamado killer de falta de memória (como mencionado acima, as políticas são configuráveis ​​no nível do espaço do usuário e o kernel não é o ideal, mas de maneira alguma desnecessário).

E é muito usado pelo Android:

Alguns aplicativos de espaço do usuário estão disponíveis para ajudar com esses aplicativos de interrupção, por exemplo:

Peter Teoh
fonte
9

Aparentemente, você encontrou a resposta desejada no comando finish (). Isso não removerá seu aplicativo da memória, mas o Android o fará sempre que precisar dos recursos, para que não faça diferença que você não faça isso explicitamente.

Gostaria de acrescentar apenas que, para atingir o efeito total que uma saída de aplicativo normalmente teria, você desejaria redefinir o estado do aplicativo para o estado que ele normalmente é no momento em que é executado pela primeira vez após a inicialização do dispositivo, pouco antes para chamar finish () em todas as suas atividades. Dessa forma, se o usuário selecionar seu aplicativo novamente, ele parecerá ter sido executado como "novo", sem nenhum estado restante do ponto anterior à "saída" simulada.

Se houver algumas ações especiais que devem ocorrer apenas na "saída", como salvar o trabalho do usuário ou o que for, você também poderá executá-las antes da parte de reinicialização da rotina acima.

Essa abordagem permite que você alcance seu objetivo de ter um comando "exit" sem violar a filosofia do Android de deixar o gerenciamento de recursos do SO, incluindo o fechamento de aplicativos, nas mãos do sistema operacional.

Pessoalmente, eu não usaria essa abordagem, porque os usuários do Android esperam que um aplicativo preserve sua continuidade quando o revisitam e, portanto, não estão acostumados com a modalidade de "sair" de um aplicativo. Em vez disso, eu daria suporte a uma função "clara" que um usuário pode chamar para redefinir o aplicativo para algum estado inicial padrão, sem a necessidade de "deixá-lo" no processo.

A única exceção seria quando o usuário apertar o botão voltar um número de vezes suficiente para fazer com que o aplicativo fechasse. Nessa situação, não há expectativa da parte do usuário de que o estado tenha sido salvo (e se houver um estado não salvo no aplicativo, você, como desenvolvedor, deverá ter o código manipulando o botão voltar que detecta esses dados não salvos e solicita que o usuário salve-o em SharedPreferences ou em um arquivo ou em outro meio não volátil).

Em relação ao system.exit (0):

Se você decidir usar system.exit (0) para fechar seu aplicativo com uma finalização grosseira (por exemplo, como resultado de um pressionamento final do botão Voltar), aviso que, embora para mim isso "funcione" e, em alguns casos, Nos casos em que foi a única maneira de fechar um aplicativo sem deixar vestígios, existe uma pequena falha no Jelly Bean quando você usa essa abordagem.

Especificamente, se você usar a lista Aplicativos Recentes para abrir seu aplicativo e, em seguida, usar o botão Voltar para fechá-lo (com esse fechamento implementado através de system.exit (0)), a lista Aplicativos Recentes ficará visível novamente, pois nunca foi fechado. Se você tocar na entrada do seu aplicativo nessa lista para executá-lo uma segunda vez a partir da mesma lista de aplicativos recentes já aberta, não haverá resposta.

Suspeito que a causa disso é que a lista de Aplicativos Recentes está mantendo uma referência ao seu aplicativo que não funcionou devido ao fato de você ter fechado o aplicativo usando system.exit (0). Um fechamento mais civilizado do seu aplicativo usando finish () pode ter informado o sistema operacional de uma maneira que permitiria atualizar sua lista de aplicativos recentes, mas o system.exit (0) aparentemente não faz isso.

Esse não é um grande problema por si só, já que poucas pessoas abrirão um aplicativo a partir de Aplicativos Recentes, sairão e abrirão imediatamente novamente na mesma lista aberta de Aplicativos Recentes. E se eles tocarem no botão home e reabrirem a lista de Aplicativos Recentes, a entrada do seu aplicativo estará lá, e será totalmente funcional. Mas acho que isso mostra que o uso de system.exit (0) pode interferir na comunicação adequada entre seu aplicativo e o sistema operacional, e isso sugere que pode haver outras consequências mais sérias e possivelmente sutis do uso dessa abordagem.

Carl
fonte
Talvez você possa remover a entrada de aplicativos recentes antes de chamar finish ()? Isso é algo que tentarei quando o tempo permitir. Eu tenho um serviço em primeiro plano com uma pequena atividade do iniciador. Como a Atividade é muito pequena, não é grande coisa se não for morta e enterrada, mas faz sentido dizer ao Android que ela pode ser executada antes do resto, se possível.
Nsandersen
9

Espero que as coisas mudem com o tempo. O usuário deve poder matar um aplicativo ou processo se o processo do aplicativo estiver em área restrita corretamente pelo sistema operacional. Há uma noção de que os aplicativos devem ser escritos perfeitamente ou o usuário usará apenas os aplicativos que seguem todas as recomendações do SDK. Eu acho que é uma tarefa difícil.

dipu
fonte
Eu sei. Os produtos da Apple são bons para alguns consumidores. Eles não são bons para desenvolvedores. O sistema operacional Android tem todo o potencial de se tornar o "sistema operacional Windows do mundo dos PCs" para celulares. pode ser ainda melhor. Já é mais aberto do que o Windows no mundo dos PCs, exceto que não nos permite escrever um gerenciador de tarefas.
dipu
7

Existe um design (relativamente) simples que permite contornar o dilema da "saída". Faça com que seu aplicativo tenha um estado "base" (atividade) que é apenas uma tela em branco. No primeiro onCreate da atividade, você pode iniciar outra atividade na qual a principal funcionalidade do seu aplicativo está. A "saída" pode ser realizada terminando () a segunda atividade e retornando à base de apenas uma tela em branco. O sistema operacional pode manter essa tela em branco na memória pelo tempo que desejar ...

Em essência, como você não pode sair para o sistema operacional, você simplesmente se transforma em um nada criado por você.

qwerty_ca
fonte
2
Boa ideia. No entanto, mesmo o término de uma atividade (ou serviço) não para o sistema operacional. Oh não, mesmo após a execução do onDestroy, todas as variáveis ​​e outras coisas ainda estão lá. Eu só vi isso em um serviço, everyting é o mesmo, embora o onDestroy foi chamado ...
Ted
2
... e, portanto, System.exit (0) ajudou =)
Ted
7

Sem uma função de saída para o desenvolvedor de aplicativos matar seu próprio aplicativo, é um design muito ruim.

Meu aplicativo precisa permitir que o usuário altere dinamicamente dados dinamicamente durante o tempo de execução e o usuário precisa reiniciar meu aplicativo para fazer o efeito de alteração, mas o Android não permitiu que o aplicativo fosse reiniciado sozinho. O sistema operacional Android tem um ciclo de vida de aplicativo de design muito ruim.

Peter Mortensen
fonte
9
public void appRestart () {Intenção i = nova Intenção (getBaseContext (), MyActivity.class); i.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (i); }
androidworkz 21/01
2
O código do comentário acima realmente funciona bem. Pelo menos você pode passar para a primeira atividade em vez da saída completa do aplicativo. :)
Harpreet
7

Para fechar um aplicativo a qualquer momento, use o FLAG_ACTIVITY_CLEAR_TOPsinalizador em Intent e, em seguida,system.exit();

Ou existe uma maneira semelhante, mas sem system.exit()quando você quiser sair, chame este método:

public void exit() {
    startActivity(new Intent(this, HomeActivity.class).
    setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK).putExtra(EXIT_FLAG, true));
}

No seu HomeActivity.onCreate()código a seguir, adicione

protected void onCreate(Bundle savedInstanceState) {
    if (getIntent().getBooleanExtra(EXIT_FLAG, false)) {
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
            finish();
        }
    }
......................

Isso funcionará sem interromper o ciclo de vida do Android.

Lemberg
fonte
7

Primeiro de tudo, nunca, nunca, nunca use System.exit (0). É como fazer uma pessoa dormir com um soco na cabeça!

Segundo: estou enfrentando esse problema. Antes de compartilhar minha solução, quero compartilhar meus pensamentos.

Eu acho que um "botão de saída" é estúpido. Realmente realmente muito estúpido. E acho que os usuários (consumidores) que solicitam um botão de saída para o seu aplicativo também são estúpidos. Eles não entendem como o sistema operacional está funcionando e como está gerenciando recursos (e faz um ótimo trabalho).

Eu acho que se você escrever um bom pedaço de código que faça as coisas certas (atualiza, salva e empurra) no momento e condições certos e usando as coisas corretas (Serviço e Receptor), ele funcionará muito bem e ninguém reclamará .

Mas para fazer isso, você precisa estudar e aprender como as coisas funcionam no Android. Enfim, esta é a minha solução para fornecer aos usuários um "botão Sair".

Criei um menu Opções sempre visível em cada atividade (eu tenho uma super atividade que faz isso).

Quando o usuário clica nesse botão, é o que acontece:

Intent intent = new Intent(this, DashBoardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

SharedPreferences settings = getSharedPreferences(getString(PREF_ID), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(FORCE_EXIT_APPLICATION, true);

  // Commit the edits!
editor.commit();
startActivity(intent);
finish();

Então, estou salvando em SharedPreferences que quero matar meu aplicativo e inicio um Intent. Por favor, olhe essas bandeiras; eles limparão todo o meu backstack, chamando minha atividade do DashBoard, que é minha atividade "em casa".

Portanto, na minha atividade do painel, eu executo esse método no onResume:

private void checkIfForceKill() {

    // CHECK IF I NEED TO KILL THE APP

    // Restore preferences
    SharedPreferences settings = getSharedPreferences(
            getString(MXMSettingHolder.PREF_ID), Context.MODE_PRIVATE);
    boolean forceKill = settings.getBoolean(
            MusicSinglePaneActivity.FORCE_EXIT_APPLICATION, false);

    if (forceKill) {

        //CLEAR THE FORCE_EXIT SETTINGS
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(FORCE_EXIT_APPLICATION, false);

        // Commit the edits!
        editor.commit();

        //HERE STOP ALL YOUR SERVICES
        finish();
    }
}

E vai funcionar muito bem.

A única coisa que não entendo por que está acontecendo é que, quando faço o último término (e verifiquei: está seguindo todo o fluxo correto de onPause → onStop → onDestroy), o aplicativo ainda está na atividade recente (mas está em branco).

Parece que a intenção mais recente (que iniciou o DashboardActivity) ainda está no sistema.

Eu tenho que cavar mais para também removê-lo.

StErMi
fonte
8
Poucos consumidores sabem o que é um sistema operacional e muito menos como ele funciona, isso não os torna estúpidos. Desejar um botão Sair / Sair / Desativar os torna normais. Quando você sai de uma sala, apaga as luzes; o mais importante é que quando sai de casa, tranca a porta e é aqui que vejo o problema da incapacidade de sair adequadamente de um programa. Deixar o programa vivo em segundo plano é um grande risco de segurança.
Squiggles
4
"Eu acho que um" botão Sair "é estúpido". A maioria dos aplicativos de software fornece um botão de saída.
IgorGanapolsky
Você disse "// AQUI PARE TODOS OS SEUS SERVIÇOS" e, em seguida, usou finish (). Os serviços Android não possuem um método finish (). Eles possuem unbindService (mConnection);
IgorGanapolsky
@ Squiggles Se você tem uma sala que apaga automaticamente todas as luzes e trava a porta ao sair, não precisa se preocupar com isso.
precisa saber é o seguinte
7

O ciclo de vida do aplicativo Android foi desenvolvido para usuários de telefones celulares, não para usuários de computadores.

O ciclo de vida do aplicativo é o paradigma brutalmente simplista necessário para transformar um servidor Linux em um dispositivo consumidor.

O Android é Java sobre Linux, um verdadeiro sistema operacional de servidor para várias plataformas. É assim que se espalhou tão rapidamente. O ciclo de vida do aplicativo encapsula a realidade subjacente do sistema operacional.

Para usuários móveis, os aplicativos estão instalados ou não. Não há conceito de correr ou sair. De fato, os processos do aplicativo devem ser executados até que o SO os libere para os recursos retidos.

Como esse é o estouro de pilha, qualquer pessoa que esteja lendo isso é um usuário de computador e deve desativar 90% de seu conhecimento para entender o ciclo de vida do aplicativo móvel.

Dominic Cerisano
fonte
Não sigo o seu salto para "os usuários de computadores devem desativar 90% do conhecimento deles". Sim, é o que Romain Guy diz, mas isso não a torna realidade. Parece-me que uma seção "Opções avançadas para usuários de computador", com um botão "Sair", atenderia às necessidades de todos.
Don escotilha
Não tenho ideia de quem é esse "Romain Guy" ou por que ele está me citando. Fechar tarefas recentes encerrará o aplicativo, assim como parar as informações do aplicativo. O ADB permite acesso ao shell para usuários avançados.
Dominic Cerisano
6

Levei mais tempo para ler estas perguntas e respostas do que para realmente implementar um ciclo de vida de aplicativos Android semi-adequado.

É um aplicativo de GPS que pesquisa pontos e envia a localização atual para um serviço da Web a cada poucos segundos usando um encadeamento ... Isso pode ser pesquisado a cada 5 minutos no caso de Ted para uma atualização, e o onStop pode simplesmente iniciar a atividade de atualização que Ted estava fazendo. preocupado em saber se foi encontrado (Ted assíncrono, não codifique como um programador do Windows ou seus programas serão executados como programas do Windows ... eww, não é tão difícil).

Eu criei um código inicial no onCreate para configurar coisas para a vida útil da atividade, incluindo checkUpdate.start();:

...

@Override
public void onStart() {
    super.onStart();
    isRemote = true;
    checkUpdate.resume();

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, luh);
}

@Override
public void onPause() {
    isRemote = false;
    checkUpdate.suspend();
    locationManager.removeUpdates(luh);
    super.onStop();
}

Este código pode estar completamente errado, mas funciona. Este é um dos meus primeiros aplicativos Android.

Voilà, um aplicativo que não consome CPU quando está em segundo plano, mas está instantaneamente pronto para reabrir porque está na RAM (embora não esteja mantendo a RAM como é o ciclo de vida do Android) ... um aplicativo está sempre pronto, é um telefone , rapazes / moças. Se um aplicativo usar toda a RAM e não puder ser desligado pelo sistema operacional, a coisa poderá parar de tocar = P É por isso que o sistema operacional precisará poder fechar o aplicativo quando estiver em segundo plano (se o aplicativo não estiver não é um recurso que não será fechado), então vamos escrever aplicativos melhores.

Brant
fonte
Você não deveria estar chamando super.onStop do método onPause. Parece que isso estragaria tudo.
Matt Wolfe
1
Depois de ler 20 ou mais respostas filosóficas que simplesmente esquivam a pergunta ... +1 por ter algum código.
Pacerier
6

Sempre que você passar para a próxima página através da intenção, use:

`YourActivityname.this.finish()`;

Exemplo:

Intent intent = new Intent(getApplicationContext(), SMS.class);

startActivity(intent);
MainActivity.this.finish();

Para que nenhuma atividade seja executada em segundo plano e quando você quiser sair do aplicativo, use:

MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();

Essa saída funcionou como um encanto para mim :)

GaneshKumar
fonte
1
Ele não sai do aplicativo; trata-se de Mainatividade.
Sharath
1
Mas tenha cuidado - onPause () NÃO é chamado no caso de killProcess e System.exit. Tivemos alguns problemas com isso.
Pavel Biryukov
4

De qualquer forma, se você deseja encerrar seu aplicativo, pode sempre ligar System.exit(0);.

Tasos Kleisas
fonte
5
System.exit()NÃO mata seu aplicativo se você tiver mais de uma atividade na pilha. Um desenvolvedor Android que o usa não entendeu o ciclo de vida básico do aplicativo Android. Leia esta resposta .
Dheeraj Vepakomma
Solução completa com System.exit(0); stackoverflow.com/questions/2033914/…
Sohail Zahid 9/16
2
Na verdade, System.exit () não matar seu aplicativo. No entanto, se o System.exit () foi chamado de outro local que não a atividade principal, o Android reiniciará o aplicativo com menos uma atividade na pilha. Para mim, isso parece uma resposta ridícula a um System.exit intencional e limpo. Quero dizer, se foi um div0 ou algum acidente não intencional, talvez seja educado reiniciar. Mas esses nem sequer causam o relançamento automático, pelo que me lembro. Mas, em qualquer caso, o aplicativo é eliminado. Pode ser reiniciado, mas isso não significa que não foi morto.
Jesse Gordon
3

Se você possui 10,20 .. várias atividades em execução e deseja concluir todas elas e sair do sistema.

Crie uma matriz estática application classouconstants class.

Constantes

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity Adicione referência de atividade atual nesta matriz

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView imageButton;
    private Activity activity;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activity = MainActivity.this;
        Constants.activities.add(activity);

        imageButton = (ImageView) findViewById(R.id.camera);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}
Sohail Zahid
fonte
1
Isso pode travar o aplicativo quando os usuários clicam em um botão duas vezes, especialmente quando o sistema está sob carga pesada por qualquer motivo. Isso pode ser evitado removendo as atividades da matriz.
que você