Preenchendo o listview em um thread separado

Em uma atividade, eu carrego linhas de um listview que leva muito tempo, portanto, coloco essa tarefa em um thread separado para permitir a exibição de um progressDialog.

Eu faço o seguinte

<code>private void doMyStuff() {
    listItems.clear();
    progressDialog.show();

    new Thread(new Runnable() {
        @Override
        public void run() {                
            for () {
                listItems.add(something to add);
            }
        handler.sendEmptyMessage(0);
        progressDialog.dismiss();
        }
    }).start();
}

private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        if (msg.what == 0) {
            adapter.notifyDataSetChanged();
        }
    };
};
</code>

Às vezes tenho um bug que gera uma IllegalStateException. Primeiro de tudo eu fiquei surpreso, porque thread de programação assim é o que eu costumo fazer em programas Java padrões.

O bug aparece apenas "às vezes" e não aparece ao fazer depuração passo a passo.

Isso me levou a pesquisar na web e encontrei algumas perguntas no SO relacionadas a isso e devo admitir que as coisas não estão claras em minha mente.

Como eu chamo o notifyDataSetChanged () somente quando o thread terminou porque às vezes ele gera uma exceção.

Alguém pode me confirmar que esta maneira de fazer é errado, e que eu devo usar a tarefa assíncrona e talvez me explicar por quê ???

Eu preciso ter um progressDialog exibido, alguém pode me dar um exemplo simples de AsyncTask preencher um listview E exibir um progressDialog do progresso de preenchimento.

obrigado

ATUALIZAR

jtanveer me deu a resposta para a pergunta asynctask. Agora os outros apontaram que a dispensa não está no manipulador, que eu corrijo.

De acordo com o artigo dado por jtanveer em "Painless Threading" eles dizem que

O Android oferece várias maneiras de acessar o encadeamento de interface do usuário a partir de outros encadeamentos, sendo que um deles é o HANDLER.

Alguém sabe por que colocar o demitido no manipulador não resolveu o meu problema? para mim listItem.add não tem nada a ver com a interface do usuário? Estou errado nesse ponto?

Para mim, no meu código, a única interface do usuário é adapter e progressdialog? Qualquer comentário ou explicação é bem-vindo.

RESPOSTA FINAL

O stjom deu uma resposta funcional para o meu código específico. Executando o runOnUiThread no manipulador. Está funcionando, mas estou surpreso porque achei que o manipulador foi executado no Ui Thread ...

Obrigado a todos por todas as suas respostas.

questionAnswers(3)

yourAnswerToTheQuestion