Pergunta

Eu tenho trabalhado com AsyncTasks no Android e estou lidando com um problema.

Tomar um exemplo simples, uma Atividade com uma AsyncTask.A tarefa no fundo não faz nada de espetacular, ele apenas dorme para 8 segundos.

No final da AsyncTask no onPostExecute() método que eu sou apenas a definição de um botão visibilidade do status para Exibir.VISÍVEL, apenas para verificar meu resultado.

Agora, isso funciona muito bem até que o utilizador decida mudar de telefones orientação, enquanto o AsyncTask trabalho (dentro dos 8 segundo dormir de janela).

Eu entendo o Android atividade do ciclo de vida e eu sei que a atividade é destruído e recriado.

Este é o lugar onde o problema vem.O AsyncTask está se referindo a um botão e, aparentemente, mantém uma referência para o contexto que começou a AsyncTask em primeiro lugar.

Eu seria de esperar, que este velho de contexto (desde que o usuário causado uma alteração de orientação) para tornar-se nulo e o AsyncTask para lançar uma NPE para a referência para o botão é tentar tornar visível.

Em vez disso, não NPE é lançada, o AsyncTask pensa que o botão de referência é não nulo, define-a visível.O resultado?Nada do que está acontecendo na tela!

Atualização: Eu tenho combatido esse mantendo uma WeakReference para a atividade de chaveamento e quando uma alteração de configuração acontece.Isso é complicado.

Aqui está o código:

public class Main extends Activity {

    private Button mButton = null;
    private Button mTestButton = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mButton = (Button) findViewById(R.id.btnStart);
        mButton.setOnClickListener(new OnClickListener () {
            @Override
            public void onClick(View v) {
                new taskDoSomething().execute(0l);
            }
        });
        mTestButton = (Button) findViewById(R.id.btnTest);   
    }

    private class TaskDoSomething extends AsyncTask<Long, Integer, Integer> 
    {
        @Override
        protected Integer doInBackground(Long... params) {
            Log.i("LOGGER", "Starting...");
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 0;
        }

        @Override
        protected void onPostExecute(Integer result) {
            Log.i("LOGGER", "...Done");
            mTestButton.setVisibility(View.VISIBLE);
        }
    }
}

Tente executá-lo e enquanto o AsyncTask está trabalhando alterar seus telefones orientação.

Foi útil?

Solução

A assíncada não foi projetada para ser reutilizada depois que uma atividade é destruída e reiniciada. O objeto de manipulador interno fica obsoleto, assim como você declarou. Nas prateleiras, exemplo de Romain Guy, ele simples cancela qualquer coisa atualmente executando o AsyncTask e reinicia novas mudanças pós-orientação.

É possível entregar seu thread à nova atividade, mas adiciona muito encanamento. Geralmente não há como fazer isso, mas você pode ler sobre o meu método aqui: http://foo.jasonhudgins.com/2010/03/simple-progressbar-tutorial.html

Outras dicas

Se você só precisa de um contexto e não usá-lo para a interface do usuário de coisas que você pode simplesmente passar o ApplicationContext para o seu AsyncTask.Você muitas vezes precisa de contexto para os recursos do sistema, por exemplo.

Não tente atualizar a INTERFACE do usuário a partir de uma AsyncTask e tentar evitar o tratamento de alterações de configuração de si mesmo como ele pode ficar confuso.A fim de atualizar a INTERFACE do usuário você pode registrar um receptor de Transmissão e enviar um Broadcast.

Você também deve ter o AsyncTask como um público de classe a partir da atividade, como mencionado acima, ele torna o teste muito mais fácil.Infelizmente o Android de programação, muitas vezes, reforça as más práticas e o oficial exemplos não estão ajudando.

Como o SharePoint 2010 e o Analysis Services 2008 estavam em máquinas separadas, eu pude ver o logon através da autenticação do Windows como domínio \ TFSReports estava sendo sucedido na máquina de serviços de análise no Visualizador de Eventos \ Logs de segurança. Então eu sabia que o Excel Services estava ficando tão longe ...

Googling em geral sobre o PF_Check_Error e "Classe não registrado", parecia algum tipo de erro com o OLEDBConnection. Qual classe ou dll poderia estar tentando carregar que não é registrada?

Bem, o tipo de conexão OLE DB é o MS OLAP, e a cadeia de conexão no arquivo ODC incorporado da folha especifica OLAP.3. Surpresa, Surpresa, OLAP 2 e 4 estão presentes na máquina de serviços de análise, mas não msolap. !! (confirmado com Regedit - HKEY_CLASSES_ROOT \ MSOLAP).

Então eu abri o relatório, alterei a cadeia de conexão para provedor= MSOLAP.4 nas propriedades de conexão do TFSOLAPReport, salva e publicada - esse relatório específico, atualizado corretamente. Eu atualizei todos os relatórios do Excel no projeto da equipe para usar o OLAP 4 e todos os painéis estão funcionando.


.

Espero que isso ajude qualquer outra pessoa a tentar usar serviços do Excel e o serviço de loja seguro - eu estava prestes a ir ainda mais longe o buraco do coelho com Kerberos, especialmente como cliente e servidor estão em diferentes domínios (mas confiáveis), mas não você Não precisa de nada disso. É realmente tão simples quanto as instruções aqui Contanto que todas as dependências estiverem instaladas corretamente!

Para obter os logs iniciais que eu poste na pergunta, tive que ativar o registro detalhado para o aplicativo do Excel Services e Secure Store Service na Administração Central> Monitoramento> Configurar o registro de diagnóstico. Os logs aparecerão em% de arquivos de programa% \ arquivos comuns \ Microsoft compartilhados \ Extensões do servidor Web \ 14 \ Logs (óbvio, hein?).

(uma coisa que ainda não está clareada é se a instalação do MSOLAP 3 na máquina de serviços de análise seria uma maneira de corrigir o problema sem alterar as cadeias de conexão. O olap é carregado pelos serviços do Excel no servidor do SharePoint ou por serviços de análise. Analysis Server? Vou confirmar quando eu receber um instalador x64 para ele).

Para evitar isso, você pode usar a resposta aqui: https://stackoverflow.com/a/2124731/327011

Mas se você precisar destruir a atividade (layouts diferentes para retrato e paisagem), pode fazer a assíncada uma aula pública (leia aqui por que não deveria ser privado Android: Recomendações de Asynctask: classe privada ou classe pública?) e, em seguida, crie uma conjunta de métodos para definir a referência à atividade atual sempre que for destruída/criada.

Você pode ver um exemplo aqui: Android AsyncTask em classe externa

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top