AsyncTask - onPostExecute não é chamado

125 views
Skip to first unread message

Guilherme Gregores

unread,
Feb 25, 2013, 12:20:04 PM2/25/13
to androidb...@googlegroups.com
Ola,

Tenho um app que funciona como um especie de Chat onde eu uso uma AsyncTask para carregar a lista da conversa, que funciona normalmente.

O meu problema na verdade é quando o aplicativo para por algum motivo (Force close, por exemplo). 

Caso uma mensagem seja recebida via GCM(onde é gerada uma notificação com um Intent para a Conversa, como qualquer Chat) após o Force close, o método OnPostExecute da AsyncTask  não é chamado. Faço a chamada da Asynctask no onCreate, segue o código:

protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
        ...
        ...
               try{
                    loadListTask = new LoadListTask();
                    loadListTask.execute();
                }catch(Exception e){
                    Log.d(TAG,"ERRO: "+e.getMessage());
                 }
      }
public void loadListView() {
        messagesDb = useful.buscarMessagesDb(this);
        ArrayList<Message> messageListViews = new ArrayList<Message>();
        int messagesDbSize = messagesDb.size();
        for (int i = 0; i < messagesDbSize; i++) {
            if (((messagesDb.get(i).idFrom == myId) && (messagesDb.get(i).idTo == idContact)) || 
                    ((messagesDb.get(i).idFrom == idContact) && (messagesDb.get(i).idTo == myId))) {
                Message message = new Message(messagesDb.get(i).idFrom, messagesDb.get(i).idTo, 
                        messagesDb.get(i).dt, messagesDb.get(i).mensagem, messagesDb.get(i).confirm,
                        messagesDb.get(i).idWeb);           
                messageListViews.add(message);
            } else {
                //Log.d(TAG, "Essa mensagem não é pra esse contato!!!");
            }
        }
            listChat.setAdapter(null);
            pref.edit().putBoolean("isUpdate", false).commit();
            AdapterMessageListView adapterMessageListView = new AdapterMessageListView(myId, idContact, 
                    getApplicationContext(), messageListViews); 
            listChat.setAdapter(adapterMessageListView);
            listChat.setCacheColorHint(Color.TRANSPARENT);
            listChat.setSelection(listChat.getCount());
    }
private class LoadListTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... params) {
        try {
            Log.d(TAG,"doInBackground");
            Thread.sleep(100);
        } catch (InterruptedException e) {

        }
        return "list";
    }

        @Override
        public void onPreExecute() {
            Log.d(TAG,"PREEXECUTE");

        }

        @Override
        protected void onPostExecute(String result) {

            Log.d(TAG,"PostExecute");
            loadListView();
            loadListTask = new LoadListTask();
            loadListTask.execute();
            super.onPostExecute(result);
        }
    }
Log:
02-25 14:05:42.396: D/Chat(20663): Do in Background
02-25 14:05:42.396: W/MessageQueue(20663): Handler{40532ad8} sending message to a Handler on a dead thread
02-25 14:05:42.396: W/MessageQueue(20663): java.lang.RuntimeException: Handler{40532ad8} sending message to a Handler on a dead thread

luciofm

unread,
Feb 25, 2013, 12:27:44 PM2/25/13
to androidb...@googlegroups.com
Isso acontece pois quando acontece um Force Close, seu aplicativo é encerrado, todo o processo é morto e nenhum código mais é executado.

Lúcio Maciel
luc...@gmail.com


--
You received this message because you are subscribed to the Google Groups "Android Brasil - Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to androidbrasil-...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Guilherme Gregores

unread,
Feb 25, 2013, 1:42:37 PM2/25/13
to androidb...@googlegroups.com
Então Lucio acho que acabei me expressando mal, a aplicação está fechada(o usuario acaba de ligar o celular ou o próprio android finaliza ele..etc), e quando uma mensagem é enviada para esse usuario, gera um notificação que abre a conversa só que não carrega a conversa salva no banco interno pois o  OnPostExecute não é chamado. 
O estranho é que se a aplicação esta aberta a notificação funciona normalmente abrindo a conversa e carregando a conversa no banco.

2013/2/25 luciofm <luc...@gmail.com>

Leonardo S

unread,
Feb 26, 2013, 10:11:20 AM2/26/13
to androidb...@googlegroups.com
Se a aplicação está fechada, não faz sentido esperar o onPostExecute, já que ele roda na UIThread.
Use BroadcastReceiver e separa o download da atualização da UI.

Guilherme Gregores

unread,
Feb 26, 2013, 12:25:34 PM2/26/13
to androidb...@googlegroups.com
Entao leonardo, quando o usuario recebe uma notificação de mensagem, se ela for clicada abre minha activity, onde tem uma lista que seria carregada pelo onPostExecute da AsyncTask, que é chamada no onCreate da activity.

Leonardo S

unread,
Feb 26, 2013, 12:54:38 PM2/26/13
to androidb...@googlegroups.com
Cara ... não vi nada de errado em seu código então. Nunca tive esse problema.
Costumo a usar no início super.onPostExecute(result);. Não sei se faz diferença.

 @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // resto
            

Guilherme Gregores

unread,
Feb 26, 2013, 1:31:41 PM2/26/13
to androidb...@googlegroups.com
Mudei aqui leonardo mas o problema continua =z, se souber de algum outro motivo para não estar funcionando me deixe informado valeu ^^.  

Bruno Albuquerque

unread,
Feb 26, 2013, 5:50:46 PM2/26/13
to androidb...@googlegroups.com
Você está batendo de frente com uma particularidade do AsyncTask. O seu código espera que ele seja inicializado na main thread mas isso não é garantido ocorrer. Como você está iniciando a sua app através de uma notificação, esse é exatamente seu problema.

Existe um workaround bem simples. No seu onCreate(), adicione isso:

Class.forName("android.os.AsyncTask");

Isso vai forçar a inicialização dos inicializadores estáticos da sua AsyncTask na main thread e deve fazer tudo funcionar.

Se quiser mais detalhes, é só dizer.

-Bruno

Guilherme Gregores

unread,
Feb 27, 2013, 2:03:16 PM2/27/13
to androidb...@googlegroups.com
Obrigado pela força Bruno, mas o problema continua. 
Coloquei Class.forName("android.os.AsyncTask"); no onCreate() da minha Activity, ele não da nem 1 problema, mas o erro ainda continua depois dele chamar o doInBackground  Handler{40530e28} sending message to a Handler on a dead thread. 
Vi algo parecido com oque voce disse no stackoverflow mas o resultado foi o mesmo. Se voce tiver mas alguma ideia do motivo ou souber de um jeito + facil de rodar minha loadlistview estou aberto a sugestões .

Bruno Albuquerque

unread,
Feb 27, 2013, 2:40:43 PM2/27/13
to androidb...@googlegroups.com
Se você conseguir isolar o problema e criar um código de teste simples que reproduz o mesmo, eu dou uma olhada pra você.

Leonardo S

unread,
Feb 27, 2013, 4:05:37 PM2/27/13
to androidb...@googlegroups.com
Guilherme,

Por que vc não tenta atualizar a UI por broadcast receiver, que é a maneira mais recomendada ?
Dessa forma, evita problema de sincronismo entre a thread de AsyncTask e da UI.
E pode conseguir isolar o problema. 

Pedro Subutzki <Pepeu>

unread,
Feb 28, 2013, 8:42:56 AM2/28/13
to androidb...@googlegroups.com
é tranquilo atualizar a UI através de um broadcast receiver.
Se quiser posso passar o esquema.
Abraços,
Pedro Subutzki
__________________________________________
HADI - Makes SQLite in Android easy and simple
https://github.com/PepeuCps/Hadi

Erick Couto

unread,
Feb 28, 2013, 9:07:08 AM2/28/13
to androidb...@googlegroups.com
+1 pedro.. desde que começei a fazer assim tudo passou a ficar mais limpo e fácil.
-----------------------------------------------------------------
Erick Couto
Java | Android | PHP

Guilherme Gregores

unread,
Feb 28, 2013, 9:21:02 AM2/28/13
to androidb...@googlegroups.com
Então Pedro, se não for muito problema pra você eu ia gostar muito ^^.

Em 28 de fevereiro de 2013 10:42, Pedro Subutzki <Pepeu> <faleco...@gmail.com> escreveu:

Gabriel Augusto

unread,
Mar 1, 2013, 2:04:10 PM3/1/13
to androidb...@googlegroups.com
Fiquei interessado em como atualizar a UI por Receiver. 

Agradeceria também se divulgasse Pedro!
Att,
Gabriel Augusto
013 97940055

Pedro Subutzki <Pepeu>

unread,
Mar 1, 2013, 2:18:12 PM3/1/13
to androidb...@googlegroups.com
Bom... basicamente você precisa criar seu IntentService da seguinte maneira:

public class SyncDataService extends IntentService {

public static final String BROADCAST = "br.com.meupacote.service.SyncDataService.BROADCAST";
private static Intent broadcast = new Intent(BROADCAST);
public SyncDataService() {
super("SyncDataService");
}

@Override
public void onHandleIntent(Intent intent) {
boolean result = server.ObterDados();
if(result)
sendOrderedBroadcast(broadcast, null);
}
}

Na sua Activity você deve o seguinte:

@Override
public void onResume() {
super.onResume();
IntentFilter filter=new IntentFilter(SyncDataService.BROADCAST);
filter.setPriority(2);
registerReceiver(onNotice, filter);
}
  
@Override
public void onPause() {
super.onPause();    
unregisterReceiver(onNotice);
}

private BroadcastReceiver onNotice = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent i) {
//AQUI você pode atualizar os dados que vc quiser da sua Activity
abortBroadcast();
}
};


Pronto! Acho que é só isso! :)
Qualquer problema me avisa!

Duanniston Cardoso Cabral

unread,
Mar 5, 2013, 9:37:05 AM3/5/13
to androidb...@googlegroups.com
Olha não seis e entendi bem ou se deixei passar alguma coisa sem ler direito.

mas isso deveria ser feito em um Service.

Reply all
Reply to author
Forward
0 new messages