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.
killProcess()
. É um motivo válido para escrever um código iOS melhor.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 seProcess.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:
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.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:
finish()
todas as atividades ou liguemoveTaskToBack(true)
.startActivity()
com um Intent que contém oIntent.FLAG_ACTIVITY_CLEAR_TOP
sinalizador.fonte
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).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.
fonte
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.
fonte
System.exit()
remove apenas uma atividade da pilha. A JVM é imediatamente reinicializada. Veja esta resposta .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.
fonte
Você pode sair pressionando o Backbotão ou ligando
finish()
para o seuActivity
. Basta ligarfinish()
de aMenuItem
se 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.
fonte
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.
fonte
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.
fonte
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:
Vá em frente e leia o artigo completo.
fonte
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.
fonte
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
fonte
Service
pensamento 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.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
fonte
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. :)
fonte
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:
Agora, para matar seu aplicativo, forneça um método 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!
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 ).
fonte
Quando concebo um aplicativo no Android, vejo o seguinte:
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".
fonte
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()
comjava.lang.System.exit(0)
(ou talvezrestartPackage(..)
?). Obviamente, faça isso apenas no caso em que você deseja "realmente finalizar o aplicativo", porque issoonDestroy()
faz parte do ciclo de vida normal das atividades e não é um fim do aplicativo.fonte
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.
fonte
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):
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.
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 ...
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.
fonte
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.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:
OOM killer não é para o espaço do usuário
Notas do Android (OOM Killer Info - onde você pode configurar o recurso OOM no Android)
Portagem Android no alvo real
Alguns aplicativos de espaço do usuário estão disponíveis para ajudar com esses aplicativos de interrupção, por exemplo:
fonte
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.
fonte
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.
fonte
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ê.
fonte
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.
fonte
Para fechar um aplicativo a qualquer momento, use o
FLAG_ACTIVITY_CLEAR_TOP
sinalizador em Intent e, em seguida,system.exit();
Ou existe uma maneira semelhante, mas sem
system.exit()
quando você quiser sair, chame este método:No seu
HomeActivity.onCreate()
código a seguir, adicioneIsso funcionará sem interromper o ciclo de vida do Android.
fonte
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:
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:
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.
fonte
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.
fonte
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();
:...
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.
fonte
Sempre que você passar para a próxima página através da intenção, use:
Exemplo:
Para que nenhuma atividade seja executada em segundo plano e quando você quiser sair do aplicativo, use:
Essa saída funcionou como um encanto para mim :)
fonte
De qualquer forma, se você deseja encerrar seu aplicativo, pode sempre ligar
System.exit(0);
.fonte
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 .System.exit(0);
stackoverflow.com/questions/2033914/…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 class
ouconstants class.
Constantes
MainActivity Adicione referência de atividade atual nesta matriz
activity = MainActivity.this; Constants.activities.add(activity);
fonte