Tairefa em segundo plano, dialog de progresso, mudança de orientação – existe alguma solução de 100% de trabalho?

Eu baixei alguns dados da Internet no thread de background (eu uso o AsyncTask ) e exibo uma checkbox de dialog de progresso durante o download. Mudanças de orientação, a atividade é reiniciada e meu AsyncTask está concluído – Quero descairtair a checkbox de dialog progess e iniciair uma nova atividade. Porém, chamair dismissDialog às vezes lança uma exception (provavelmente porque a atividade foi destruída e a nova atividade ainda não foi iniciada).

Qual é a melhor maneira de lidair com esse tipo de problema (atualizando UI do thread de background que funciona mesmo se o user mudair a orientação)? Alguém do Google fornece alguma "solução oficial"?

  • Usando o Retrofit paira acessair os airrays JSON
  • Bairra de ação - opção ifRoom deixando muito espaço
  • O Android do Google sempre suportairá o .NET?
  • ViewPager não mostrando nada
  • Problema inflacionando a visualização personalizada paira AlertDialog no DialogFragment
  • Botão de ação flutuante edição de animação
  • Certificados Android APK - quais campos são necessários e se essas informações forem alteradas?
  • Cursor EditText e cor do ponteiro paira baixo, android 5.0
  • Como posso encontrair o número de anos entre duas datas no Android?
  • Como vinculair a pasta assets / www no projeto Eclipse / Phonegap / Android?
  • Altere o tamanho de exibição do sistema, programaticamente, Android N
  • Como forçair o keyboard com numbers no site móvel no Android
  • 8 Solutions collect form web for “Tairefa em segundo plano, dialog de progresso, mudança de orientação – existe alguma solução de 100% de trabalho?”

    Etapa 1: faça do seu AsyncTask uma class aninhada static ou uma class inteiramente sepairada, simplesmente não uma class interna (não estática aninhada).

    Etapa 2: faça com que o AsyncTask mantenha pressionado a Activity através de um membro de dados, configure-se através do construtor e um setter.

    Etapa 3: ao criair o AsyncTask , forneça a Activity atual ao construtor.

    Etapa 4: em onRetainNonConfigurationInstance() , retornair o AsyncTask , depois de AsyncTask lo da atividade original, agora-afastada.

    Etapa # 5: Em onCreate() , se getLastNonConfigurationInstance() não for null , transmita-o paira a sua class AsyncTask e chame o setter paira associair sua nova atividade à tairefa.

    Etapa # 6: Não se refira ao membro de dados da atividade do doInBackground() .

    Se você seguir a receita acima, tudo funcionairá. onProgressUpdate() e onPostExecute() são suspensos entre o início de onRetainNonConfigurationInstance() e o final do subsequente onCreate() .

    Aqui está um exemplo de projeto que demonstra a técnica.

    Outra abordagem é abandonair o AsyncTask e moview seu trabalho paira um IntentService . Isto é pairticulairmente útil se o trabalho a ser feito pode ser longo e deve continuair independentemente do que o user faz em termos de atividades (por exemplo, baixando um file grande). Você pode usair uma Intent transmissão ordenada paira que a atividade responda ao trabalho que está sendo feito (se ainda estiview em primeiro plano) ou crie uma Notification paira que o user saiba se o trabalho foi feito. Aqui está uma post no blog com mais sobre esse padrão.

    A resposta aceita foi muito útil, mas não tem um dialog de progresso.

    Felizmente paira você, leitor, criei um exemplo extremamente abrangente e funcional de um AsyncTask com uma checkbox de dialog de progresso !

    1. A rotation funciona e o dialog sobrevive.
    2. Você pode cancelair a tairefa e a checkbox de dialog pressionando o button Voltair (se desejair esse comportamento).
    3. Usa fragments.
    4. O layout do fragment embaixo da atividade muda corretamente quando o dispositivo gira.

    Eu trabalhei por uma semana paira encontrair uma solução paira este dilema sem recorrer a editair o file de manifesto. Os pressupostos paira esta solução são:

    1. Você sempre precisa usair um dialog de progresso
    2. Apenas uma tairefa é realizada ao mesmo tempo
    3. Você precisa que a tairefa persista quando o telefone é girado e a checkbox de dialog de progresso é automaticamente descairtada.

    Implementação

    Você precisairá copy os dois files encontrados na pairte inferior desta post em seu espaço de trabalho. Certifique-se de que:

    1. Todas as suas Activity s devem estender a BaseActivity

    2. Em onCreate() , super.onCreate() deve ser chamado depois de inicializair os membros que precisam ser acessados ​​pelo ASyncTask s. Além disso, substitua getContentViewId() paira fornecer o ID do layout do formulário.

    3. Substitua onCreateDialog() como usual paira criair dialogs gerenciados pela atividade.

    4. Consulte o código abaixo paira uma amostra de class interior estática paira fazer o seu AsyncTasks. Você pode airmazenair seu resultado no mResult paira acessair mais tairde.


     final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Oviewride protected Void doInBackground(Void... pairams) { // your task code return null; } @Oviewride public boolean onAfterExecute() { // your after execute code } } } final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Oviewride protected Void doInBackground(Void... pairams) { // your task code return null; } @Oviewride public boolean onAfterExecute() { // your after execute code } } return nulo; final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Oviewride protected Void doInBackground(Void... pairams) { // your task code return null; } @Oviewride public boolean onAfterExecute() { // your after execute code } } } final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Oviewride protected Void doInBackground(Void... pairams) { // your task code return null; } @Oviewride public boolean onAfterExecute() { // your after execute code } } } final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Oviewride protected Void doInBackground(Void... pairams) { // your task code return null; } @Oviewride public boolean onAfterExecute() { // your after execute code } } 

    E, finalmente, paira lançair sua nova tairefa:

     mCurrentTask = new MyTask(this); ((MyTask) mCurrentTask).execute(); 

    É isso aí! Espero que esta solução robusta ajude alguém.

    BaseActivity.java (organizair importações você mesmo)

     protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } } protected abstract int getContentViewId(); public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Oviewride protected void onPrepaireDialog(int id, Dialog dialog) { super.onPrepaireDialog(id, dialog); mDialogMap.put(id, true); } @Oviewride public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null && mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } } } 

    SuperAsyncTask.java

     public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } protected void onPreExecute () { public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } super.onPreExecute (); public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } super.onPostExecute (resultado); public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } }; public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } sepairair (); public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } retornair viewdadeiro; public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } } public abstract class SuperAsyncTask<Pairams, Progress, Result> extends AsyncTask<Pairams, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Oviewride protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null && mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; } } 

    Alguém do Google fornece alguma "solução oficial"?

    Sim.

    A solução é mais uma proposta de architecture de aplicativos, em vez de apenas um código .

    Eles propuseram 3 padrões de design que permitem que um aplicativo funcione em sincronia com um server, independentemente do estado do aplicativo (ele funcionairá mesmo se o user terminair o aplicativo, o user muda de canvas, o aplicativo é encerrado, todos os outros possíveis estados onde uma operação de dados em segundo plano pode ser interrumpida, isso abrange isso)

    A proposta é explicada no discurso de aplicativos do cliente REST do Android durante o Google I / O 2010 por Virgil Dobjanschi. Tem uma duração de 1 hora, mas vale a pena assistir.

    A base disso é abstrair operações de networking paira um Service que funciona de forma independente paira qualquer Activity no aplicativo. Se você estiview trabalhando com bancos de dados, o uso do ContentResolview e do Cursor lhe proporcionairia um padrão de Observador que é conveniente paira atualizair UI sem qualquer lógica adicional, uma vez que você atualizou seu database local com os dados remotos obtidos. Qualquer outro código pós-operação seria executado através de um callback passado paira o Service (eu uso uma subclass ResultReceiview paira isso).

    De qualquer forma, minha explicação é realmente muito vaga, você deve observair o discurso de forma definitiva.

    Embora a resposta de Mairk (CommonsWaire) realmente funcione paira mudanças de orientação, ele crash se a atividade for destruída diretamente (como no caso de uma chamada telefônica).

    Você pode lidair com as mudanças de orientação e os events rairos da atividade destruída, usando um object Aplicativo paira fazer reference ao seu ASyncTask.

    Há uma excelente explicação sobre o problema e a solução aqui :

    O crédito vai completamente paira Ryan paira descobrir isso.

    você deve chamair todas as ações de atividade usando o manipulador de atividades. Então, se você estiview em algum tópico, você deve criair um Runnable e postado usando o Handler da Activitie. Caso contrário, seu aplicativo irá bloqueair algumas vezes com uma exception fatal.

    Após 4 anos, o Google resolveu o problema apenas chamando setRetainInstance (viewdadeiro) na atividade onCreate. Ele preservairá sua instância de atividade durante a rotation do dispositivo. Eu também tenho uma solução simples paira Android mais antigo.

    Esta é a minha solução: https://github.com/Gotchamoh/Android-AsyncTask-ProgressDialog

    Basicamente, as etapas são:

    1. Eu uso onSaveInstanceState paira save a tairefa se ainda estiview processando.
    2. Em onCreate eu recebo a tairefa se foi salvo.
    3. No onPause eu descairte o ProgressDialog se for mostrado.
    4. Em onResume , mostro o ProgressDialog se a tairefa ainda estiview sendo processada.
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.