Meu programa realiza alguma atividade de rede em um encadeamento em segundo plano. Antes de iniciar, aparece uma caixa de diálogo de progresso. A caixa de diálogo é descartada no manipulador. Isso tudo funciona bem, exceto quando a orientação da tela muda enquanto a caixa de diálogo está aberta (e a linha de fundo está em andamento). Nesse momento, o aplicativo trava, entra em conflito ou entra em um estágio estranho em que o aplicativo não funciona até que todos os threads tenham sido eliminados.
Como lidar com a mudança de orientação da tela normalmente?
O código de exemplo abaixo corresponde aproximadamente ao que meu programa real faz:
public class MyAct extends Activity implements Runnable {
public ProgressDialog mProgress;
// UI has a button that when pressed calls send
public void send() {
mProgress = ProgressDialog.show(this, "Please wait",
"Please wait",
true, true);
Thread thread = new Thread(this);
thread.start();
}
public void run() {
Thread.sleep(10000);
Message msg = new Message();
mHandler.sendMessage(msg);
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mProgress.dismiss();
}
};
}
Pilha:
E/WindowManager( 244): Activity MyAct has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@433b7150 that was originally added here
E/WindowManager( 244): android.view.WindowLeaked: Activity MyAct has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@433b7150 that was originally added here
E/WindowManager( 244): at android.view.ViewRoot.<init>(ViewRoot.java:178)
E/WindowManager( 244): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:147)
E/WindowManager( 244): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:90)
E/WindowManager( 244): at android.view.Window$LocalWindowManager.addView(Window.java:393)
E/WindowManager( 244): at android.app.Dialog.show(Dialog.java:212)
E/WindowManager( 244): at android.app.ProgressDialog.show(ProgressDialog.java:103)
E/WindowManager( 244): at android.app.ProgressDialog.show(ProgressDialog.java:91)
E/WindowManager( 244): at MyAct.send(MyAct.java:294)
E/WindowManager( 244): at MyAct$4.onClick(MyAct.java:174)
E/WindowManager( 244): at android.view.View.performClick(View.java:2129)
E/WindowManager( 244): at android.view.View.onTouchEvent(View.java:3543)
E/WindowManager( 244): at android.widget.TextView.onTouchEvent(TextView.java:4664)
E/WindowManager( 244): at android.view.View.dispatchTouchEvent(View.java:3198)
Tentei descartar a caixa de diálogo de progresso no onSaveInstanceState, mas isso apenas impede uma falha imediata. O encadeamento em segundo plano ainda está em andamento e a interface do usuário está no estado parcialmente desenhado. Precisa matar o aplicativo inteiro antes que ele comece a funcionar novamente.
fonte
Respostas:
Quando você muda de orientação, o Android cria uma nova visualização. Você provavelmente está tendo falhas porque o thread de segundo plano está tentando alterar o estado do antigo. (Também pode estar com problemas porque o encadeamento em segundo plano não está no encadeamento da interface do usuário)
Eu sugeriria tornar esse mHandler volátil e atualizá-lo quando a orientação mudar.
fonte
Edit: Os engenheiros do Google não recomendam essa abordagem, conforme descrito por Dianne Hackborn (também conhecido como hackbod ) neste post do StackOverflow . Verificação de saída esta postagem no blog para obter mais informações.
Você deve adicionar isso à declaração de atividade no manifesto:
então parece
O problema é que o sistema destrói a atividade quando ocorre uma alteração na configuração. Vejo ConfigurationChanges .
Portanto, colocar isso no arquivo de configuração evita que o sistema destrua sua atividade. Em vez disso, chama o
onConfigurationChanged(Configuration)
métodofonte
orientation
, existem muitas outras razões para a configuração mudar:keyboardHidden
(já editei a resposta da wiki),uiMode
(por exemplo, entrar ou sair do modo carro; mudar o modo noturno), etc. Agora me pergunto se isso é realmente uma boa respostaEu vim com uma solução sólida para esses problemas que está em conformidade com o 'Modo Android'. Eu tenho todas as minhas operações de longa duração usando o padrão IntentService.
Ou seja, minhas atividades intenções de transmissão, o IntentService faz o trabalho, salva os dados no banco de dados e, em seguida, transmite pegajosas intenções. A parte complicada é importante, de modo que, mesmo que a Atividade tenha sido interrompida durante o período após o usuário iniciar o trabalho e perca a transmissão em tempo real do IntentService, ainda podemos responder e coletar os dados da Atividade que está chamando.
ProgressDialog
s podem trabalhar muito bem com esse padrãoonSaveInstanceState()
.Basicamente, você precisa salvar um sinalizador que possui uma caixa de diálogo de progresso em execução no pacote configurável da instância salva. Não salve o objeto de diálogo de progresso, pois isso vazará toda a atividade. Para ter um identificador persistente da caixa de diálogo de progresso, eu a armazeno como uma referência fraca no objeto de aplicativo. Na mudança de orientação ou qualquer outra coisa que faça com que a Atividade seja pausada (telefonema, o usuário chega em casa etc.) e, em seguida, continuo, eu rejeito a caixa de diálogo antiga e recrio uma nova caixa de diálogo na Atividade recém-criada.
Para diálogos de progresso indefinidos, isso é fácil. Para o estilo da barra de progresso, você deve colocar o último progresso conhecido no pacote e as informações que estiver usando localmente na atividade para acompanhar o progresso. Ao restaurar o progresso, você usará essas informações para gerar novamente a barra de progresso no mesmo estado de antes e depois atualizar com base no estado atual das coisas.
Então, para resumir, colocar tarefas de longa execução em um IntentService, juntamente com o uso criterioso de,
onSaveInstanceState()
permite acompanhar de maneira eficiente os diálogos e restaurar, em seguida, os eventos do ciclo de vida da Atividade. Os bits relevantes do código de atividade estão abaixo. Você também precisará de lógica no seu BroadcastReceiver para lidar com as intenções fixas, mas isso está além do escopo.fonte
Eu encontrei o mesmo problema. Minha atividade precisa analisar alguns dados de um URL e é lenta. Então, crio um thread para fazer isso e mostro uma caixa de diálogo de progresso. Deixei o tópico postar uma mensagem de volta no tópico da interface do usuário via
Handler
quando terminar. EmHandler.handleMessage
, pego o objeto de dados (pronto agora) do encadeamento e o preencho na interface do usuário. Portanto, é muito parecido com o seu exemplo.Após várias tentativas e erros, parece que encontrei uma solução. Pelo menos agora eu posso girar a tela a qualquer momento, antes ou depois do término da discussão. Em todos os testes, a caixa de diálogo é fechada corretamente e todos os comportamentos são esperados.
O que eu fiz é mostrado abaixo. O objetivo é preencher meu modelo de dados (
mDataObject
) e preenchê-lo na interface do usuário. Deve permitir a rotação da tela a qualquer momento sem surpresa.Isso é o que funciona para mim. Não sei se esse é o método "correto", conforme projetado pelo Android - eles afirmam que essa "atividade de destruir / recriar durante a rotação da tela" facilita as coisas, então acho que não deve ser muito complicado.
Deixe-me saber se você encontrar um problema no meu código. Como dito acima, eu realmente não sei se há algum efeito colateral.
fonte
onRetainNonConfigurationInstance()
egetLastNonConfigurationInstance()
me ajudou a resolver meu problema. Afirmativo!O problema percebido original era que o código não sobreviveria a uma alteração na orientação da tela. Aparentemente, isso foi "resolvido", fazendo com que o programa lide com a orientação da tela, mudando a si próprio, em vez de permitir que a estrutura da interface do usuário faça isso (chamando onDestroy)).
Eu diria que, se o problema subjacente é que o programa não sobreviverá ao Destroy (), a solução aceita é apenas uma solução alternativa que deixa o programa com outros problemas e vulnerabilidades sérios. Lembre-se de que a estrutura do Android afirma especificamente que sua atividade corre o risco de ser destruída quase a qualquer momento devido a circunstâncias fora de seu controle. Portanto, sua atividade deve ser capaz de sobreviver a onDestroy () e subsequente onCreate () por qualquer motivo, não apenas uma alteração na orientação da tela.
Se você aceitar as alterações na orientação da tela para resolver o problema do OP, será necessário verificar se outras causas de onDestroy () não resultam no mesmo erro. Você é capaz de fazer isso? Caso contrário, eu perguntaria se a resposta "aceita" é realmente muito boa.
fonte
Minha solução foi estender a
ProgressDialog
aula para obter a minhaMyProgressDialog
.I redefinido
show()
edismiss()
métodos para bloquear a orientação antes de mostrar oDialog
e desbloqueá-lo de volta quandoDialog
é indeferido. Portanto, quandoDialog
é mostrado e a orientação do dispositivo muda, a orientação da tela permanece até quedismiss()
seja chamada, e a orientação da tela muda de acordo com os valores do sensor / orientação do dispositivo.Aqui está o meu código:
fonte
Enfrentei esse mesmo problema e encontrei uma solução que não era invulgar usando o ProgressDialog e obtive resultados mais rápidos.
O que fiz foi criar um layout que contenha uma ProgressBar.
Em seguida, no método onCreate, faça o seguinte
Em seguida, execute a tarefa longa em um encadeamento e, quando terminar, um Runnable defina a exibição do conteúdo para o layout real que você deseja usar para esta atividade.
Por exemplo:
Foi o que fiz e descobri que ele roda mais rápido do que mostrar o ProgressDialog e é menos invasivo e tem uma aparência melhor na minha opinião.
No entanto, se você deseja usar o ProgressDialog, essa resposta não é para você.
fonte
setContentView(R.layout.my_layout);
não é suficiente; você precisa definir todos os ouvintes, redefinir dados etc.Eu descobri uma solução para isso que ainda não vi em outro lugar. Você pode usar um objeto de aplicativo personalizado que saiba se você tem tarefas em segundo plano, em vez de tentar fazer isso na atividade que é destruída e recriada na mudança de orientação. Eu escrevi sobre isso aqui .
fonte
Application
é normalmente usada para manter um estado global do aplicativo. Não digo que não funcione, mas parece complicado demais. No documento "Normalmente não há necessidade de subclassificar Aplicativo.". Eu prefiro a resposta de sonxurxo.Contribuirei com minha abordagem para lidar com esse problema de rotação. Isso pode não ser relevante para o OP, pois ele não está usando
AsyncTask
, mas talvez outros achem útil. É bem simples, mas parece fazer o trabalho para mim:Eu tenho uma atividade de logon com uma
AsyncTask
classe aninhada chamadaBackgroundLoginTask
.No meu,
BackgroundLoginTask
eu não faço nada fora do comum, exceto para adicionar uma verificação nula ao cancelar a chamadaProgressDialog
:Isso é para lidar com o caso em que a tarefa em segundo plano termina enquanto
Activity
não está visível e, portanto, a caixa de diálogo de progresso já foi descartada peloonPause()
método.Em seguida, na minha
Activity
classe pai , crio identificadores estáticos globais para minhaAsyncTask
classe e minhaProgressDialog
(aAsyncTask
, sendo aninhada, pode acessar essas variáveis):Isso serve para dois propósitos: primeiro, ele permite que eu
Activity
sempre acesse oAsyncTask
objeto mesmo a partir de uma nova atividade pós-rotacionada. Segundo, ele permiteBackgroundLoginTask
acessar e descartar oProgressDialog
mesmo após uma rotação.Em seguida, adiciono isso a
onPause()
, fazendo com que a caixa de diálogo de progresso desapareça quandoActivity
sairmos do primeiro plano (impedindo o feio travamento "forçar fechamento"):Finalmente, tenho o seguinte no meu
onResume()
método:Isso permite
Dialog
que reapareça após aActivity
recriação.Aqui está toda a turma:
Eu não sou um desenvolvedor Android experiente, então fique à vontade para comentar.
fonte
Mova a tarefa longa para uma classe separada. Implemente-o como um padrão de observador de assunto. Sempre que a atividade é criada, registre-se e, ao fechar, cancele o registro com a classe de tarefa. A classe de tarefa pode usar AsyncTask.
fonte
O truque é mostrar / descartar a caixa de diálogo no AsyncTask durante onPreExecute / onPostExecute, como de costume, embora, no caso de mudança de orientação, crie / mostre uma nova instância da caixa de diálogo na atividade e passe sua referência para a tarefa.
fonte
Eu fiz assim:
Você também pode tentar e me avise que funciona para você ou não
fonte
Se você criar um plano de fundo
Service
que faça todo o trabalho pesado (solicitações / resposta tcp, desserialização), oView
eActivity
poderá ser destruído e recriado sem vazar janela ou perder dados. Isso permite o comportamento recomendado pelo Android, que é destruir uma Atividade em cada alteração na configuração (por exemplo, para cada alteração na orientação).É um pouco mais complexo, mas é a melhor maneira de chamar solicitação de servidor, pré / pós-processamento de dados, etc.
Você pode até usar o seu
Service
para enfileirar cada solicitação em um servidor, tornando mais fácil e eficiente lidar com essas coisas.O guia do desenvolvedor tem um capítulo
Services
completo .fonte
Service
é mais trabalho que um,AsyncTask
mas pode ser uma abordagem melhor em algumas situações. Não é necessariamente melhor, é? Dito isto, não entendo como isso resolve o problema doProgressDialog
que vazou do principalActivity
. Onde você instanciaProgressDialog
? Onde você o dispensa?Eu tenho uma implementação que permite que a atividade seja destruída em uma alteração na orientação da tela, mas ainda destrói o diálogo na atividade recriada com êxito. Eu uso
...NonConfigurationInstance
para anexar a tarefa em segundo plano à atividade recriada. A estrutura normal do Android lida com a recriação da própria caixa de diálogo, nada é alterado lá.Subclassifiquei o AsyncTask adicionando um campo para a atividade 'proprietária' e um método para atualizar esse proprietário.
Na minha classe de atividade, adicionei um campo
backgroundTask
referente à tarefa de fundo 'de propriedade' e atualizo esse campo usandoonRetainNonConfigurationInstance
egetLastNonConfigurationInstance
.Sugestões para melhorias adicionais:
backgroundTask
referência na atividade após a conclusão da tarefa para liberar qualquer memória ou outros recursos associados a ela.ownerActivity
referência na tarefa em segundo plano antes que a atividade seja destruída, caso não seja recriada imediatamente.BackgroundTask
interface e / ou coleção para permitir que diferentes tipos de tarefas sejam executados a partir da mesma atividade proprietária.fonte
Se você mantiver dois layouts, todo o thread da interface do usuário deve ser encerrado.
Se você usar o AsynTask, poderá chamar facilmente o
.cancel()
método dentro doonDestroy()
método da atividade atual.Para o AsyncTask, leia mais na seção "Cancelando uma tarefa" aqui .
Atualização: condição adicionada para verificar o status, pois só pode ser cancelado se estiver no estado de execução. Observe também que o AsyncTask pode ser executado apenas uma vez.
fonte
Tentou implementar a solução da jfelectron porque é uma " solução sólida para esses problemas que está em conformidade com o 'Modo Android' ", mas levou algum tempo para procurar e reunir todos os elementos mencionados. Acabei com essa solução um pouco diferente, e acho mais elegante, postada aqui na íntegra.
Usa um IntentService acionado a partir de uma atividade para executar a tarefa de execução longa em um encadeamento separado. O serviço lança de volta intenções de transmissão persistentes para a atividade que atualiza a caixa de diálogo. A Atividade usa showDialog (), onCreateDialog () e onPrepareDialog () para eliminar a necessidade de passar dados persistentes no objeto de aplicativo ou no pacote salvoInstanceState. Isso deve funcionar, independentemente de como seu aplicativo seja interrompido.
Classe de atividade:
Classe IntentService:
Entradas de arquivo de manifesto:
antes da seção de aplicação:
seção de aplicação interna
fonte
Esta é a minha solução proposta:
void showProgressDialog()
método pode ser adicionado à interface do ouvinte de atividade de fragmento para esse fim.fonte
Eu enfrentei a mesma situação. O que fiz foi obter apenas uma instância para o meu diálogo de progresso em todo o aplicativo.
Primeiro, criei uma classe DialogSingleton para obter apenas uma instância (padrão Singleton)
Como mostro nesta classe, tenho o diálogo de progresso como atributo. Sempre que preciso mostrar uma caixa de diálogo de progresso, obtenho a instância exclusiva e crio um novo ProgressDialog.
Quando termino a tarefa em segundo plano, chamo novamente a instância exclusiva e encerro sua caixa de diálogo.
Eu salvo o status da tarefa em segundo plano nas minhas preferências compartilhadas. Ao girar a tela, pergunto se tenho uma tarefa em execução para esta atividade: (onCreate)
Quando começo a executar uma tarefa em segundo plano:
Quando eu terminar de executar uma tarefa em segundo plano:
Espero que ajude.
fonte
Essa é uma pergunta muito antiga que surgiu na barra lateral por algum motivo.
Se a tarefa em segundo plano precisar sobreviver apenas enquanto a atividade estiver em primeiro plano, a "nova" solução será hospedar o encadeamento em segundo plano (ou, de preferência,
AsyncTask
) em um fragmento retido , conforme descrito neste guia do desenvolvedor e em várias perguntas e respostas .Um fragmento retido sobrevive se a atividade for destruída por uma alteração na configuração, mas não quando a atividade for destruída em segundo plano ou na pilha traseira. Portanto, a tarefa em segundo plano ainda deve ser interrompida se
isChangingConfigurations()
for falsaonPause()
.fonte
Eu sou um novato no Android e tentei isso e deu certo.
fonte
Eu tentei TUDO. Passou dias experimentando. Eu não queria impedir que a atividade girasse. Meu cenário foi:
O problema foi que, ao girar a tela, todas as soluções do livro falharam. Mesmo com a classe AsyncTask, que é a maneira correta do Android de lidar com essas situações. Ao girar a tela, o Contexto atual com o qual o thread inicial está trabalhando desaparece e isso atrapalha a caixa de diálogo exibida. O problema sempre foi o Diálogo, não importa quantos truques eu adicionei ao código (passando novos contextos para os threads em execução, mantendo os estados dos threads através de rotações, etc ...). A complexidade do código no final sempre foi enorme e sempre havia algo que poderia dar errado.
A única solução que funcionou para mim foi o truque Activity / Dialog. É simples e genial e é tudo à prova de rotação:
Em vez de criar um Diálogo e pedir para mostrá-lo, crie uma Atividade que foi definida no manifesto com android: theme = "@ android: style / Theme.Dialog". Então, parece apenas um diálogo.
Substitua showDialog (DIALOG_ID) por startActivityForResult (yourActivityDialog, yourCode);
Use onActivityResult na atividade de chamada para obter os resultados do encadeamento em execução (mesmo os erros) e atualizar a interface do usuário.
Em seu 'ActivityDialog', use threads ou AsyncTask para executar tarefas longas e onRetainNonConfigurationInstance para salvar o estado de "diálogo" ao girar a tela.
Isso é rápido e funciona bem. Ainda uso diálogos para outras tarefas e o AsyncTask para algo que não requer um diálogo constante na tela. Mas com esse cenário, eu sempre busco o padrão Atividade / Diálogo.
E não tentei, mas é possível impedir que a Atividade / Diálogo gire, quando o thread estiver em execução, acelerando as coisas, enquanto permite que a Atividade que está chamando gire.
fonte
Intent
, que é mais restritivo do que oObject
permitido porAsyncTask
Atualmente, existe uma maneira muito mais distinta de lidar com esses tipos de problemas. A abordagem típica é:
1. Verifique se seus dados estão separados adequadamente da interface do usuário:
Qualquer coisa que seja um processo em segundo plano deve ser mantida
Fragment
(defina-a comFragment.setRetainInstance()
. Isso se torna seu 'armazenamento de dados persistente', onde são mantidos os dados com base nos quais você deseja reter. Após o evento de mudança de orientação,Fragment
ele ainda estará acessível em seu original estado através de umaFragmentManager.findFragmentByTag()
chamada (quando você a cria, deve atribuir a ela uma tag, não um ID, pois não está anexado aView
).Consulte o guia desenvolvido Handling Runtime Changes para obter informações sobre como fazer isso corretamente e por que é a melhor opção.
2. Verifique se você está interagindo corretamente e com segurança entre os processos em segundo plano e sua interface do usuário:
Você deve reverter seu processo de vinculação. No momento, seu processo em segundo plano se anexa a um
View
- em vez disso, vocêView
deve se anexar ao processo em segundo plano. Faz mais sentido, certo? AView
ação da depende do processo em segundo plano, enquanto o processo em segundo plano não depende doView
. Isso significa alterar o link para umaListener
interface padrão . Diga que seu processo (seja qual for a classe - seja umaAsyncTask
,Runnable
seja qual for) define umOnProcessFinishedListener
, quando o processo é feito ele deve chamar esse ouvinte se ele existir.Esta resposta é uma boa descrição concisa de como fazer ouvintes personalizados.
3. Vincule sua interface do usuário ao processo de dados sempre que a interface do usuário for criada (incluindo alterações de orientação):
Agora você deve se preocupar com a interface da tarefa em segundo plano com a
View
estrutura atual . Se você estiver lidando com as mudanças de orientação corretamente (e não asconfigChanges
pessoas sempre recomendam), vocêDialog
será recriado pelo sistema. Isso é importante, significa que, na mudança de orientação, todosDialog
os métodos do ciclo de vida do seu são recuperados. Portanto, em qualquer um desses métodos (onCreateDialog
geralmente é um bom lugar), você pode fazer uma chamada da seguinte maneira:Consulte o ciclo de vida do fragmento para decidir onde a configuração do ouvinte se encaixa melhor na sua implementação individual.
Essa é uma abordagem geral para fornecer uma solução robusta e completa para o problema genérico solicitado nesta pergunta. Provavelmente faltam algumas partes menores nessa resposta, dependendo do cenário individual, mas essa geralmente é a abordagem mais correta para lidar adequadamente com os eventos de mudança de orientação.
fonte
Eu encontrei uma solução mais fácil de lidar com tópicos quando a orientação muda. Você pode apenas manter uma referência estática à sua atividade / fragmento e verificar se é nula antes de agir na interface do usuário. Sugiro usar um try catch também:
fonte
Se você está com dificuldades para detectar eventos de mudança de orientação de um diálogo INDEPENDENTE DE UMA REFERÊNCIA DE ATIVIDADE , esse método funciona muito bem. Eu uso isso porque tenho minha própria classe de diálogo que pode ser mostrada em várias atividades diferentes, portanto nem sempre sei em qual atividade está sendo exibida. Com esse método, você não precisa alterar o AndroidManifest, preocupe-se com as referências de atividade, e você não precisa de uma caixa de diálogo personalizada (como eu tenho). Você precisa, no entanto, de uma exibição de conteúdo personalizada para poder detectar as alterações de orientação usando essa exibição específica. Aqui está o meu exemplo:
Configuração
Implementação 1 - Diálogo
Implementação 2 - AlertDialog.Builder
Implementação 3 - ProgressDialog / AlertDialog
fonte
Esta é minha solução quando a enfrentei:
ProgressDialog
não é umaFragment
criança, portanto minha classe personalizada "ProgressDialogFragment
" pode se estenderDialogFragment
para manter a caixa de diálogo mostrada para alterações na configuração.Existem 2 abordagens para resolver isso:
Primeira abordagem: faça a atividade que utiliza o diálogo para reter o estado durante a alteração de configuração no arquivo de manifesto:
Essa abordagem não é preferida pelo Google.
Segunda abordagem: no
onCreate()
método da atividade , você deve reter o seuDialogFragment
, reconstruindo oProgressDialogFragment
novamente com o título e a mensagem da seguinte forma, sesavedInstanceState
não for nulo:fonte
Parece muito "rápido e sujo" para ser verdade, por favor, aponte as falhas, mas o que eu achei funcionou foi ...
No método onPostExecute do meu AsyncTask, simplesmente agrupei o '.dismiss' da caixa de diálogo de progresso em um bloco try / catch (com um catch vazio) e simplesmente ignorei a exceção que foi gerada. Parece errado, mas parece que não há efeitos negativos (pelo menos para o que estou fazendo posteriormente, que é iniciar outra atividade que passa no resultado da minha consulta de longa duração como Extra)
fonte
Activity
tem uma referência aoDialog
. Quando a configuração é alterada, a primeiraActivity
é destruída, o que significa que todos os campos estão definidos comonull
. Mas o nível inferiorWindowManager
também tem uma referência aoDialog
(já que ainda não foi descartado). O novoActivity
tenta criar um novoDialog
(inpreExecute()
) e o gerenciador de janelas gera uma exceção fatal, impedindo que você faça isso. De fato, se o fizer, não haveria maneira de destruir de maneira limpa aDialog
portanto mantendo uma referência à inicialActivity
. Estou certo?A solução mais simples e flexível é usar um AsyncTask com uma referência estática ao ProgressBar . Isso fornece uma solução encapsulada e, portanto, reutilizável para problemas de mudança de orientação. Essa solução me serviu bem para diversas tarefas assíncronas, incluindo downloads da Internet, comunicação com os Serviços e verificações do sistema de arquivos. A solução foi bem testada em várias versões do Android e modelos de telefone. Uma demonstração completa pode ser encontrada aqui com interesse específico em DownloadFile.java
Apresento o seguinte como exemplo de conceito
O uso em uma atividade do Android é simples
fonte
Quando você muda as orientações, o Android elimina essa atividade e cria uma nova atividade. Eu sugiro usar o retrofit com o Rx java. que lida com falhas automaticamente.
Use esse método ao atualizar a chamada.
.subscribeOn (Schedulers.io ()) .observeOn (AndroidSchedulers.mainThread ())
fonte