Eu tenho essas duas aulas. Minha Atividade principal e a que estende o AsyncTask
Agora, na minha Atividade principal, preciso obter o resultado do OnPostExecute()
no AsyncTask
. Como posso passar ou obter o resultado para minha Atividade principal?
Aqui estão os códigos de amostra.
Minha atividade principal.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
Esta é a classe AsyncTask
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
android
android-asynctask
Stella
fonte
fonte
Respostas:
Fácil:
Crie uma
interface
classe, ondeString output
é opcional, ou pode ser qualquer variável que você deseja retornar.Vá para a sua
AsyncTask
turma e declare a interfaceAsyncResponse
como um campo:Na sua atividade principal, você precisa fazer a
implements
interfaceAsyncResponse
.ATUALIZAR
Eu não sabia que isso é o favorito de muitos de vocês. Então, aqui está a maneira simples e conveniente de usar
interface
.ainda usando o mesmo
interface
. Para sua informação, você pode combinar isso emAsyncTask
classe.na
AsyncTask
aula:faça isso na sua
Activity
classeOu, implementando a interface na Atividade novamente
Como você pode ver 2 soluções acima, a primeira e a terceira, ela precisa criar o método
processFinish
, a outra, o método está dentro do parâmetro do chamador. A terceira é mais organizada porque não há classe anônima aninhada. Espero que isto ajudeDica : Mudança
String output
,String response
eString result
para diferentes tipos de correspondência, a fim de obter diferentes objetos.fonte
Existem algumas opções:
Aninhe a
AsyncTask
classe dentro da suaActivity
classe. Supondo que você não use a mesma tarefa em várias atividades, essa é a maneira mais fácil. Todo o seu código permanece o mesmo, basta mover a classe de tarefa existente para uma classe aninhada dentro da classe da sua atividade.Crie um construtor personalizado para o seu
AsyncTask
que faça referência ao seuActivity
. Você instanciaria a tarefa com algo parecidonew MyAsyncTask(this).execute(param1, param2)
.fonte
static
? Basta usar qualquerfieldOrMethod
deMyActivity
ouMyActivity.this.fieldOrMethod
se é sombreada.MyAsyncTask
é uma classe interna.private
/protected
para as classes de nível superior não é permitido, portanto, pensei que deveria ser umastatic
classe não interna.Eu senti a abordagem abaixo é muito fácil.
Eu declarei uma interface para retorno de chamada
Tarefa assíncrona criada para responder a todos os tipos de solicitações paralelas
Em seguida, chamou a tarefa assíncrona ao clicar em um botão na atividade Classe.
obrigado
fonte
Você pode tentar esse código na sua classe principal. Isso funcionou para mim, mas eu implementei métodos de outra maneira
fonte
execute()
, veja minha resposta, eu adicionei um comentário lá. convém verificar minha resposta atualizada. espero que isto ajude.Esta resposta pode estar atrasada, mas eu gostaria de mencionar algumas coisas quando você
Activity
dependeAsyncTask
. Isso ajudaria você a evitar falhas e gerenciamento de memória. Como já mencionado nas respostas acimainterface
, também os chamamos de retorno de chamada. Eles funcionarão como informantes, mas nunca enviarão uma referência forteActivity
ouinterface
sempre usarão uma referência fraca nesses casos.Consulte a captura de tela abaixo para descobrir como isso pode causar problemas.
Como você pode ver se começamos
AsyncTask
com uma referência forte , não há garantia de que nossoActivity
/Fragment
estará vivo até obtermos dados; portanto, seria melhor usáWeakReference
-lo nesses casos e que também ajudará no gerenciamento de memória, pois nunca manteremos a forte referência de nossaActivity
então será elegível para coleta de lixo após sua distorção.Verifique o trecho de código abaixo para descobrir como usar o WeakReference incrível -
MyTaskInformer.java
Interface que funcionará como um informador.MySmallAsyncTask.java
AsyncTask para executar tarefas de longa duração, que serão usadasWeakReference
.MainActivity.java
Esta classe é usada para iniciar meuAsyncTask
implementointerface
nesta classe eoverride
neste método obrigatório.fonte
no seu Oncreate ():
`
} `
fonte
Você pode fazer isso em poucas linhas, substituindo onPostExecute ao chamar sua AsyncTask. Aqui está um exemplo para você:
Espero que tenha ajudado, codificação feliz :)
fonte
onPostExecute
método.Por que as pessoas tornam isso tão difícil?
Isso deve ser suficiente.
Não implemente o onPostExecute na tarefa assíncrona; em vez disso, implemente-o na atividade:
fonte
@Override
?Você pode chamar o
get()
método deAsyncTask
(ou sobrecarregadoget(long, TimeUnit)
). Esse método será bloqueado até que o trabalhoAsyncTask
seja concluído e, nesse momento, ele retornará oResult
.Seria sensato fazer outro trabalho entre a criação / início da tarefa assíncrona e chamar o
get
método, caso contrário, você não está utilizando a tarefa assíncrona com muita eficiência.fonte
Você pode escrever seu próprio ouvinte. É o mesmo que a resposta de HelmiB , mas parece mais natural:
Crie uma interface de ouvinte:
Em seguida, escreva sua tarefa assíncrona:
Por fim, implemente o ouvinte na atividade:
E é assim que você pode chamar asyncTask:
fonte
Oi, você pode fazer algo parecido com isto:
Criar classe que implementa AsyncTask
Adicionar na Atividade Principal
fonte
Crie um membro estático na sua classe Activity. Em seguida, atribua o valor durante o
onPostExecute
Por exemplo, se o resultado do seu AsyncTask for uma String, crie uma string estática pública em sua Activity
public static String dataFromAsyncTask;
Em seguida, no
onPostExecute
AsyncTask, faça uma chamada estática para sua classe principal e defina o valor.MainActivity.dataFromAsyncTask = "result blah";
fonte
Eu faço funcionar usando encadeamento e manipulador / mensagem. Etapas a seguir: Declarar um diálogo de progresso
Crie uma função para fechar o diálogo quando a operação estiver concluída.
Codifique os detalhes da sua execução:
fonte
Você precisa usar "protocolos" para delegar ou fornecer dados para o
AsynTask
.Delegados e fontes de dados
Um delegado é um objeto que age em nome ou em coordenação com outro objeto quando esse objeto encontra um evento em um programa. ( Definição da Apple )
protocolos são interfaces que definem alguns métodos para delegar alguns comportamentos.
Aqui está um exemplo completo !!!
fonte
tente isto:
E exemplo de uso:
fonte
Provavelmente exagerando um pouco, mas forneci retornos de chamada para o código de execução e os resultados. obviamente, para segurança do encadeamento, você deve ter cuidado com o que acessa no retorno de chamada de execução.
A implementação do AsyncTask:
Um retorno de chamada:
E, finalmente, a execução da tarefa assíncrona:
fonte
Espero que você tenha passado por isso , se não, leia.
https://developer.android.com/reference/android/os/AsyncTask
Dependendo da natureza dos dados do resultado, você deve escolher a melhor opção possível.
É uma ótima opção para usar um interface
algumas outras opções seriam ..
Se a classe AsyncTask for definida dentro da mesma classe em que você deseja usar o resultado.Use uma variável global estática ou get () , use-a da classe externa ( variável volátil, se necessário). mas deve estar ciente do progresso do AsyncTask ou, pelo menos, garantir que ela tenha concluído a tarefa e o resultado esteja disponível por meio do método global de variável / get (). você pode usar polling, onProgressUpdate (Progress ...) , sincronização ou interfaces (o que melhor lhe convier)
Se o resultado for compatível com uma entrada sharedPreference ou se for possível salvar como um arquivo na memória, você poderá salvá-lo mesmo da própria tarefa em segundo plano e usar o método onPostExecute ()
para ser notificado quando o resultado estiver disponível em a memória.
Se a sequência for pequena o suficiente e deve ser usada com o início de uma atividade. é possível usar intenções ( putExtra () ) dentro de onPostExecute () , mas lembre-se de que contextos estáticos não são tão seguros de lidar.
Se possível, você pode chamar um método estático a partir do método onPostExecute (), com o resultado sendo seu parâmetro
fonte