Android: como posso passar parâmetros para onPreExecute () de AsyncTask?

116

Eu uso um AsyncTaskpara carregar operações que implementei como uma classe interna.

Em onPreExecute(), mostro uma caixa de diálogo de carregamento, na qual oculto novamente onPostExecute(). Mas para algumas das operações de carregamento, eu sei de antemão que elas serão concluídas muito rapidamente, então não quero exibir a caixa de diálogo de carregamento.

Eu queria indicar isso por um parâmetro booleano que eu pudesse passar, onPreExecute()mas aparentemente por algum motivo onPreExecute()não leva nenhum parâmetro.

A solução alternativa óbvia provavelmente seria criar um campo de membro em minha AsyncTask ou na classe externa que eu teria que definir antes de cada operação de carregamento, mas isso não parece muito elegante. Existe uma maneira melhor de fazer isso?

Steven Meliopoulos
fonte

Respostas:

231

Você pode substituir o construtor. Algo como:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    public MyAsyncTask(boolean showLoading) {
        super();
        // do stuff
    }

    // doInBackground() et al.
}

Então, ao chamar a tarefa, faça algo como:

new MyAsyncTask(true).execute(maybe_other_params);

Editar: isso é mais útil do que criar variáveis ​​de membro porque simplifica a invocação da tarefa. Compare o código acima com:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Felix
fonte
3
Isso é exatamente o que eu fiz agora. Eu ainda preciso de uma variável de membro, mas na AsyncTask e não na classe externa, se é isso que você quer dizer. Isso é o que eu fiz: private class MyAsyncTask extends AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // fazer coisas} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos de
1
Sim, essa foi a ideia :)
Felix
1
Na verdade, você não precisa de super () no construtor AsynkTask.
ostergaard
62

1) Para mim, essa é a maneira mais simples de passar parâmetros para uma tarefa assíncrona.

// To call the async task do it like this
Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);

Declare e use a tarefa assíncrona como aqui

private class myAsyncTask extends AsyncTask<Boolean, Void, Void> {

    @Override
    protected Void doInBackground(Boolean...pParams) 
    {
        Boolean param1, param2, param3;

        //

          param1=pParams[0];    
          param2=pParams[1];
          param3=pParams[2];    
      ....
}                           

2) Passando métodos para async-task Para evitar codificar a infraestrutura async-Task (thread, messagenhandler, ...) várias vezes, você pode considerar passar os métodos que devem ser executados em sua async-task como um parâmetro. O exemplo a seguir descreve essa abordagem. Além disso, pode ser necessário criar uma subclasse da tarefa assíncrona para passar os parâmetros de inicialização no construtor.

 /* Generic Async Task    */
interface MyGenericMethod {
    int execute(String param);
}

protected class testtask extends AsyncTask<MyGenericMethod, Void, Void>
{
    public String mParam;                           // member variable to parameterize the function
    @Override
    protected Void doInBackground(MyGenericMethod... params) {
        //  do something here
        params[0].execute("Myparameter");
        return null;
    }       
}

// to start the asynctask do something like that
public void startAsyncTask()
{
    // 
    AsyncTask<MyGenericMethod, Void, Void>  mytest = new testtask().execute(new MyGenericMethod() {
        public int execute(String param) {
            //body
            return 1;
        }
    });     
}
Karl
fonte
11

por que, como e quais parâmetros são passados ​​para Asynctask <>, veja os detalhes aqui . Acho que é a melhor explicação.

A documentação do Android do Google diz que:

Uma tarefa assíncrona é definida por 3 tipos genéricos, chamados Params, Progress e Result, e 4 etapas, chamadas onPreExecute, doInBackground, onProgressUpdate e onPostExecute.

Tipos genéricos de AsyncTask:

Os três tipos usados ​​por uma tarefa assíncrona são os seguintes:

Params, o tipo dos parâmetros enviados para a tarefa na execução. Progresso, o tipo de unidades de progresso publicadas durante o cálculo em segundo plano. Resultado, o tipo de resultado do cálculo em segundo plano. Nem todos os tipos são sempre usados ​​por uma tarefa assíncrona. Para marcar um tipo como não utilizado, basta usar o tipo Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Você pode consultar mais: http://developer.android.com/reference/android/os/AsyncTask.html

Ou você pode esclarecer qual é a função de AsyncTask consultando o blog de Sankar-Ganesh

Bem, a estrutura de uma classe AsyncTask típica é assim:

private class MyTask extends AsyncTask<X, Y, Z>

    protected void onPreExecute(){ 

    } 

Este método é executado antes de iniciar o novo Thread. Não há valores de entrada / saída, então apenas inicialize as variáveis ​​ou o que você achar que precisa fazer.

protected Z doInBackground(X...x){

}

O método mais importante da classe AsyncTask. Você tem que colocar aqui todas as coisas que deseja fazer em segundo plano, em um tópico diferente do principal. Aqui temos como valor de entrada um array de objetos do tipo “X” (Você vê no cabeçalho? Temos “... extends AsyncTask” Estes são os TIPOS dos parâmetros de entrada) e retorna um objeto do tipo “Z”.

protected void onProgressUpdate (Y y) {

} Este método é chamado com o método publishProgress (y) e geralmente é utilizado quando você deseja mostrar qualquer progresso ou informação na tela principal, como uma barra de progresso mostrando o progresso da operação que você está fazendo em segundo plano.

protected void onPostExecute (Z z) {

} Este método é chamado depois que a operação em segundo plano é concluída. Como parâmetro de entrada, você receberá o parâmetro de saída do método doInBackground.

E quanto aos tipos X, Y e Z?

Como você pode deduzir da estrutura acima:

X  The type of the input variables value you want to set to the background process. This can be an array of objects.

 Y  The type of the objects you are going to enter in the onProgressUpdate method.

 Z  The type of the result from the operations you have done in the background process.

Como chamamos essa tarefa de uma classe externa? Apenas com as duas linhas a seguir:

MyTask myTask = new MyTask();

myTask.execute(x);

Onde x é o parâmetro de entrada do tipo X.

Assim que tivermos nossa tarefa em execução, podemos descobrir seu status “de fora”. Usando o método “getStatus ()”.

myTask.getStatus (); e podemos receber o seguinte status:

RUNNING - indica que a tarefa está em execução.

PENDENTE - Indica que a tarefa ainda não foi executada.

FINISHED - indica que onPostExecute (Z) terminou.

Dicas sobre como usar AsyncTask

Não chame os métodos onPreExecute, doInBackground e onPostExecute manualmente. Isso é feito automaticamente pelo sistema.

Você não pode chamar uma AsyncTask dentro de outra AsyncTask ou Thread. A chamada do método execute deve ser feita no UI Thread.

O método onPostExecute é executado no UI Thread (aqui você pode chamar outra AsyncTask!).

Os parâmetros de entrada da tarefa podem ser um array de objetos, desta forma você pode colocar quaisquer objetos e tipos que desejar.

Jamali Naveed
fonte
4

Você pode passar o parâmetro no construtor da tarefa ou ao chamar execute:

AsyncTask<Object, Void, MyTaskResult>

O primeiro parâmetro (Object) é passado em doInBackground. O terceiro parâmetro (MyTaskResult) é retornado por doInBackground. Você pode alterá-los para os tipos que desejar. Os três pontos significam que zero ou mais objetos (ou uma matriz deles) podem ser passados ​​como argumento (s).

public class MyActivity extends AppCompatActivity {

    TextView textView1;
    TextView textView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);    
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);

        String input1 = "test";
        boolean input2 = true;
        int input3 = 100;
        long input4 = 100000000;

        new MyTask(input3, input4).execute(input1, input2);
    }

    private class MyTaskResult {
        String text1;
        String text2;
    }

    private class MyTask extends AsyncTask<Object, Void, MyTaskResult> {
        private String val1;
        private boolean val2;
        private int val3;
        private long val4;


        public MyTask(int in3, long in4) {
            this.val3 = in3;
            this.val4 = in4;

            // Do something ...
        }

        protected void onPreExecute() {
            // Do something ...
        }

        @Override
        protected MyTaskResult doInBackground(Object... params) {
            MyTaskResult res = new MyTaskResult();
            val1 = (String) params[0];
            val2 = (boolean) params[1];

            //Do some lengthy operation    
            res.text1 = RunProc1(val1);
            res.text2 = RunProc2(val2);

            return res;
        }

        @Override
        protected void onPostExecute(MyTaskResult res) {
            textView1.setText(res.text1);
            textView2.setText(res.text2);

        }
    }

}
amor ao vivo
fonte