Ejemplo de Android AsyncTask


680

Estaba leyendo sobre AsyncTask, y probé el programa simple a continuación. pero no parece funcionar. ¿Cómo puedo hacer que funcione?

public class AsyncTaskActivity extends Activity {

    Button btn;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            for(int i=0;i<5;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

Solo intento cambiar la etiqueta después de 5 segundos en el proceso en segundo plano.

Este es mi main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

1
También puede mostrar el progreso llamando a PubliveProgress () desde el método doInBackground ().
osum


Aquí hay un ejemplo asinctask de descarga de imágenes también: android-ios-tutorials.com/182/…
Houcine

AsyncTask - Patrón de diseño: stackoverflow.com/questions/5058661/…
HenryChuang

3
ejemplo simple ... Debe leer el enlace
c49

Respuestas:


702

Ok, estás intentando acceder a la GUI a través de otro hilo. Esto, en general, no es una buena práctica.

AsyncTask ejecuta todo doInBackground()dentro de otro hilo, que no tiene acceso a la GUI donde están sus vistas.

preExecute()y postExecute()ofrecerle acceso a la GUI antes y después de que ocurra el trabajo pesado en este nuevo hilo, e incluso puede pasar el resultado de la operación larga postExecute()para luego mostrar los resultados del procesamiento.

Vea estas líneas donde luego está actualizando su TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Póngalos adentro onPostExecute().

Luego verá su texto TextView actualizado después de que se doInBackgroundcomplete.

Noté que su oyente onClick no verifica qué Vista ha sido seleccionada. Encuentro que la forma más fácil de hacerlo es a través de declaraciones de cambio. Tengo una clase completa editada a continuación con todas las sugerencias para evitar confusiones.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;
    AsyncTask<?, ?, ?> runningTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = findViewById(R.id.button1);

        // Because we implement OnClickListener, we only
        // have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        // Detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            if (runningTask != null)
                runningTask.cancel(true);
            runningTask = new LongOperation();
            runningTask.execute();
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel running task(s) to avoid memory leaks
        if (runningTask != null)
            runningTask.cancel(true);
    }

    private final class LongOperation extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // We were cancelled; stop sleeping!
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed"); // txt.setText(result);
            // You might want to change "executed" for the returned string
            // passed into onPostExecute(), but that is up to you
        }
    }
}

2
No puedo hacer esto <code> btn.setOnClickListener (this); </code> Eclipse da un error ----- "El método setOnClickListener (View.OnClickListener) en el tipo Vista no es aplicable para los argumentos (AsyncTaskActivity)"
Fox

Aconsejaría cambiar la configuración del texto para que no sea estática, pero tome el argumento del onPostExecute(String result)método. Para los futuros lectores, sería más claro que el argumento está poblado por el valor de retorno de doInBackground(String... params).
Eric

@Eric Tobias: Eso ya se hizo exactamente en la sección de comentarios. Seguí y respondí la pregunta de los usuarios en mi ejemplo completo.
Graham Smith

1
Como anexo y buscador de Google (y viniendo de alguien que actualmente está aprendiendo estas cosas, así es como me encontré con esto): la mayoría de las actualizaciones de la interfaz de usuario que harás para algo en lo que necesites informar el progreso al usuario está en la llamada de vuelta en ProgressUpdate que se ejecuta en el hilo principal de la interfaz de usuario.
RichieHH

1
Esto seguramente arruinará si su actividad se rota o se destruye por cualquier motivo ...
Sam

792

Mi respuesta completa está aquí , pero aquí hay una imagen explicativa para complementar las otras respuestas en esta página. Para mí, entender hacia dónde iban todas las variables fue la parte más confusa al principio.

ingrese la descripción de la imagen aquí


3
paramses una matriz (En el ejemplo anterior, era una Stringmatriz). Esto le permite pasar múltiples parámetros del mismo tipo. A continuación, puede acceder a esos parámetros con params[0], params[1], params[2], etc. En el ejemplo, sólo había una sola Stringen la paramsmatriz. Si necesita pasar varios parámetros de diferentes tipos (por ejemplo, ay Stringan int), consulte esta pregunta .
Suragch

73

Estoy seguro de que se está ejecutando correctamente, pero está intentando cambiar los elementos de la interfaz de usuario en el subproceso de fondo y eso no funcionará.

Revise su llamada y AsyncTask de la siguiente manera:

Clase de llamada

Nota: Yo personalmente sugiero usar onPostExecute()donde sea que ejecute su hilo AsyncTask y no en la clase que extiende AsyncTask en sí. Creo que hace que el código sea más fácil de leer, especialmente si necesita AsyncTask en varios lugares para manejar los resultados de manera ligeramente diferente.

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

Clase LongThread (extiende AsyncTask):

@Override
protected String doInBackground(String... params) {
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return "Executed";
}      

77
Gracias por proporcionar un ejemplo que desacopla la AsyncTask de la Actividad
sthomps

1
Sí, finalmente alguien desacopla la tarea y la actividad. gracias. Y anular el onPostExecuteen la actividad es brillante.
mcy

58

Concepto y código aquí

He creado un ejemplo simple para usar AsyncTask de Android. Comienza con onPreExecute(), doInBackground(), publishProgress()y finalmente onProgressUpdate().

En esto, doInBackground () funciona como un subproceso de fondo, mientras que otros funciona en el subproceso de la interfaz de usuario. No puede acceder a un elemento de la interfaz de usuario en doInBackground (). La secuencia es la misma que he mencionado.

Sin embargo, si necesita actualizar cualquier tipo de artilugio de doInBackground, se puede publishProgresspartir de doInBackgroundla cual va a llamar onProgressUpdatepara actualizar su widget de interfaz de usuario.

class TestAsync extends AsyncTask<Void, Integer, String> {
    String TAG = getClass().getSimpleName();

    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround", "On doInBackground...");

        for (int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a) {
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

Llámalo así en tu actividad:

new TestAsync().execute();

Referencia del desarrollador aquí


3
las clases comienzan generalmente con letras mayúsculas en Java, esa es una notación que generalmente se sigue
Vamsi Pavan Mahesh

20

Mueve estas dos líneas:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

fuera de su AsyncTask's doInBackground método y ponerlos en el onPostExecutemétodo. Su AsyncTaskdebe ser algo como esto:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}

Hola, estoy ejecutando una tarea asincrónica en el servicio, quiero devolver algún valor al hilo principal de la interfaz de usuario.
Dipen

@Dipen - Mira esta discusión . Hay dos problemas: informar los resultados de un AsyncTask, que mi respuesta aborda; y enviando un valor de un servicio al hilo ui, que aborda la otra discusión. Estos problemas son independientes.
Ted Hopp

14

Antecedentes / Teoría

AsyncTask le permite ejecutar una tarea en un subproceso en segundo plano, mientras publica los resultados en el subproceso de la interfaz de usuario.

El usuario siempre debe poder interactuar con la aplicación, por lo que es importante evitar bloquear el hilo principal (UI) con tareas como descargar contenido de la web.

Es por eso que usamos un AsyncTask.

Ofrece una interfaz sencilla al envolver la cola de mensajes de la interfaz de usuario y el controlador que le permiten enviar y procesar objetos y mensajes ejecutables desde otros hilos .

Implementación

AsyncTask es una clase genérica. (Toma tipos parametrizados en su constructor).

Utiliza estos tres tipos genéricos:

Params - el tipo de los parámetros enviados a la tarea tras la ejecución.

Progress - el tipo de las unidades de progreso publicadas durante el cálculo en segundo plano.

Result - el tipo del resultado del cálculo de fondo.

No todos los tipos son utilizados siempre por una tarea asincrónica. Para marcar un tipo como no utilizado, simplemente use el tipo Void:

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

Estos tres parámetros corresponden a tres funciones principales en las que puede anular AsyncTask:

  • doInBackground(Params...)
  • onProgressUpdate(Progress...)
  • onPostExecute(Result)

Para ejecutar AsyncTask

  • Llamada execute()con parámetros que se enviarán a la tarea en segundo plano.

Lo que pasa

  1. En el hilo principal / UI , onPreExecute()se llama.

    • Para inicializar algo en este hilo. (Por ejemplo, muestra una barra de progreso en la interfaz de usuario).
  2. En un hilo de fondo , doInBackground(Params...)se llama.

    • ( Paramsse pasaron por execute.)
    • Donde debe suceder la tarea de larga duración.
    • Debe anular al menos doInBackground()para usar AsyncTask.

    • Llame publishProgress(Progress...)para actualizar la interfaz de usuario con una pantalla de progreso (p. Ej., Animación de la interfaz de usuario o texto de registro impreso) mientras el cálculo en segundo plano aún se está ejecutando.

      • Causas onProgressUpdate()de ser llamado.
  3. En el hilo de fondo se devuelve un resultado doInBackground().

    • (Esto desencadena el siguiente paso).
  4. En el hilo principal / UI , onPostExecute()se llama con el resultado devuelto.

Ejemplos

En ambos ejemplos, la "tarea de bloqueo" es una descarga desde la web.

  • El ejemplo A descarga una imagen y la muestra en un ImageView, mientras
  • El ejemplo B descarga algunos archivos .

Ejemplo A

El doInBackground()método descarga la imagen y la almacena en un objeto de tipo BitMap. El onPostExecute()método toma el mapa de bits y lo coloca en ImageView.

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

Ejemplo B

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

Ejemplo de ejecución B

new DownloadFilesTask().execute(url1, url2, url3);

Muy agradable ... Pero sigo recibiendo errores sobre el tipo de retorno en conflicto, intentando usar un tipo de retorno incompatible. He intentado todo tipo de tipos de retorno, el mismo error.
John Ktejik

Hola @johnktejik, es posible que desees buscar ese problema específico. Tal vez esto es lo que te está sucediendo: the-return-type-is-incompatible-with-asynctask
TT--

1
¡Excelente! Considere ir a la edición ?
Peter Mortensen el

12

Cuando se ejecuta una tarea asincrónica, la tarea sigue cuatro pasos:

  1. onPreExecute ()
  2. doInBackground (Parámetros ...)
  3. onProgressUpdate (Progreso ...)
  4. onPostExecute (Resultado)

A continuación se muestra un ejemplo de demostración:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));

            // Escape early if cancel() is called
            if (isCancelled())
                break;
        }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
 }

Y una vez que creó, una tarea se ejecuta de manera muy simple:

new DownloadFilesTask().execute(url1, url2, url3);

execute espera un paremeter como Runnable. No acepta cadena. ¿Cuál es el tipo de tu url? string or not

10

El ejemplo más corto para hacer algo de forma asincrónica:

class MyAsyncTask extends android.os.AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        // Do something asynchronously
        return null;
    }
}

Para ejecutarlo:

(new MyAsyncTask()).execute();

10

¿Cómo memorizar los parámetros utilizados en AsyncTask?

No

Si es nuevo en AsyncTask, es muy común confundirse al escribir AsyncTask. Los principales culpables son los parámetros utilizados en la AsyncTask, es decir, AsyncTask<A, B, C>. Con base en la firma A, B, C (argumentos) de los métodos, esto hace que las cosas sean aún más confusas.

¡Mantenlo simple!

La clave es no memorizar . Si puede visualizar lo que su tarea realmente necesita hacer, escribir AsyncTask con la firma correcta en el primer intento sería pan comido. Solo averigua cuáles son tus Input, Progressy Outputeres, y estarás listo para comenzar.

Entonces, ¿qué es una AsyncTask?

AsyncTask es una tarea en segundo plano que se ejecuta en el subproceso en segundo plano. Toma un Input, realiza Progressy da un Output.

Es decir , AsyncTask<Input, Progress, Output>.

Por ejemplo:

Ingrese la descripción de la imagen aquí

¿Cuál es la relación con los métodos?

Entre AsyncTaskydoInBackground()

Ingrese la descripción de la imagen aquí

doInBackground()y onPostExecute(),onProgressUpdate () `también están relacionados

Ingrese la descripción de la imagen aquí

¿Cómo escribir eso en el código?

DownloadTask extends AsyncTask<String, Integer, String>{

    // Always same signature
    @Override
    public void onPreExecute()
    {}

    @Override
    public String doInbackGround(String... parameters)
    {
        // Download code
        int downloadPerc = // Calculate that
        publish(downloadPerc);

        return "Download Success";
    }

    @Override
    public void onPostExecute(String result)
    {
        super.onPostExecute(result);
    }

    @Override
    public void onProgressUpdate(Integer... parameters)
    {
        // Show in spinner, and access UI elements
    }

}

¿Cómo ejecutarás esta tarea?

new DownLoadTask().execute("Paradise.mp3");

6

Cuando está en el subproceso de trabajo, no puede manipular directamente los elementos de la interfaz de usuario en Android.

Cuando utilice AsyncTask, comprenda los métodos de devolución de llamada.

Por ejemplo:

public class MyAyncTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // Here you can show progress bar or something on the similar lines.
        // Since you are in a UI thread here.
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // After completing execution of given task, control will return here.
        // Hence if you want to populate UI elements with fetched data, do it here.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        // You can track you progress update here
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Here you are in the worker thread and you are not allowed to access UI thread from here.
        // Here you can perform network operations or any heavy operations you want.
        return null;
    }
}

FYI: para acceder al subproceso de la interfaz de usuario desde un subproceso de trabajo, utilice el método runOnUiThread () o el método de publicación en su vista.

Por ejemplo:

runOnUiThread(new Runnable() {
    textView.setText("something.");
});

or
    yourview.post(new Runnable() {
    yourview.setText("something");
});

Esto te ayudará a conocer mejor las cosas. Por lo tanto, en su caso, debe establecer su vista de texto en el método onPostExecute ().



3

Ejemplo de tarea asíncrona con solicitud POST:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();

class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
    String URL;
    List<NameValuePair> parameters;

    private ProgressDialog pDialog;

    public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
    {
        this.URL = url;
        this.parameters = params;
    }

    @Override
    protected void onPreExecute()
    {
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Processing Request...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            HttpPost httpPost = new HttpPost(URL);

            if (parameters != null)
            {
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            httpResponse = httpClient.execute(httpPost);

            httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity);

        }  catch (Exception e)
        {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result)
    {
        pDialog.dismiss();

        try
        {

        }
        catch (Exception e)
        {

        }
        super.onPostExecute(result);
    }
}


1

Debe declarar el botón onclicklistener. Una vez que se hace clic, llama a la clase AsyncTask DownloadJson.

El proceso se mostrará a continuación:

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

        btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DownloadJson().execute();
            }
        });
    }

    // DownloadJSON AsyncTask
    private class DownloadJson extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            newlist = new ArrayList<HashMap<String, String>>();
            json = jsonParser.makeHttpRequest(json, "POST");
            try {
                newarray = new JSONArray(json);
                    for (int i = 0; i < countdisplay; i++) {
                        HashMap<String, String> eachnew = new HashMap<String, String>();
                        newobject = newarray.getJSONObject(i);
                        eachnew.put("id", newobject.getString("ID"));
                        eachnew.put("name", newobject.getString("Name"));
                        newlist.add(eachnew);
                    }
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            newlisttemp.addAll(newlist);
            NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
            newpager.setAdapter(newadapterpager);
        }
    }

1
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Showing progress dialog
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {

        // Do code here

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        // Dismiss the progress dialog
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    protected void onCancelled() {

        super.onCancelled();
        progressDialog.dismiss();
        Toast toast = Toast.makeText(
                          getActivity(),
                          "An error is occurred due to some problem",
                          Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();
    }

}


0

Ejemplo de ejemplo de AsyncTask con progreso

import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn;
    ProgressBar progressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);
        progressBar = (ProgressBar)findViewById(R.id.pbar);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                new LongOperation().execute("");
                break;
        }
    }

    private class LongOperation extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.d("AsyncTask", "doInBackground");
            for (int i = 0; i < 5; i++) {
                try {
                    Log.d("AsyncTask", "task "+(i + 1));
                    publishProgress(i + 1);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "Completed";
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d("AsyncTask", "onPostExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText(result);
            progressBar.setProgress(0);
        }

        @Override
        protected void onPreExecute() {
            Log.d("AsyncTask", "onPreExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onPreExecute");
            progressBar.setMax(500);
            progressBar.setProgress(0);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d("AsyncTask", "onProgressUpdate "+values[0]);
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onProgressUpdate "+values[0]);

            ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
            animation.setDuration(1000);
            animation.setInterpolator(new LinearInterpolator());
            animation.start();
        }
    }
}

0

Tarea ASync;

public class MainActivity extends AppCompatActivity {

    private String ApiUrl = "your_api";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyTask myTask = new MyTask();
        try {
            String result=myTask.execute(ApiUrl).get();
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }

    public class MyTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {

            String result = "";
            HttpURLConnection httpURLConnection = null;
            URL url;

            try {
                url = new URL(strings[0]);
                httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                result = getData(reader);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

        public String getData(InputStreamReader reader) throws IOException {

            String result = "";
            int data = reader.read();
            while (data!=-1) {
                char now = (char) data;
                result += data;
                data = reader.read();
            }
            return result;
        }
    }

}

¿Por qué la clase está MyTaskdentro de la clase MainActivity? ¿Es eso habitual?
Peter Mortensen el

0

Mientras trabaja con AsyncTask, es necesario crear un sucesor de clase y en él registrar la implementación de los métodos necesarios para nosotros. En esta lección veremos tres métodos:

doInBackground : se ejecutará en un nuevo hilo y aquí resolveremos todas nuestras tareas difíciles. Porque un subproceso no primario no tiene acceso a la interfaz de usuario.

onPreExecute : ejecutado antes de doInBackground y tiene acceso a la interfaz de usuario

onPostExecute : ejecutado después de doInBackground (no funciona si se canceló AsyncTask, sobre esto en las próximas lecciones) y tiene acceso a la interfaz de usuario.

Esta es la clase MyAsyncTask:

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

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    tvInfo.setText("Start");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Your background method
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    tvInfo.setText("Finish");
  }
}

Y así es como llamar a su Actividad o Fragmento:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();

Re "sobre esto en las próximas lecciones" : ¿A qué se refiere eso? Por ejemplo, ¿de dónde se toma esto?
Peter Mortensen el

0

si abre la clase AsyncTask, puede ver el código a continuación.

public abstract class AsyncTask<Params, Progress, Result> {
    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    @MainThread
    protected void onPreExecute() {
    }
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }
}

Funciones de AsyncTask

  1. AsyncTask es una clase abstracta
  2. AsyncTask tiene 3 parámetros genéricos.
  3. AsyncTask tiene un método abstracto de doInBackground, onPreExecute, onPostExecute
  4. doInBackground es WorkerThread (no puede actualizar la interfaz de usuario)
  5. onPreExecute es MainThread
  6. onPostExecute es MainThread (puede actualizar la interfaz de usuario)

ejemplo

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email);

    AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
        @Override
        protected Post doInBackground(Void... params) {
            try {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
                ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
                Bearer.setApiKey(authorization);
                PostApi apiInstance = new PostApi();
                String id = "1"; // String | id
                Integer commentPage = 1; // Integer | Page number for Comment
                Integer commentPer = 10; // Integer | Per page number For Comment
                Post result;
                try {
                    result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
                } catch (ApiException e) {
                    e.printStackTrace();
                    result = new Post();
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                return new Post();
            }
        }

        @Override
        protected void onPostExecute(Post post) {
            super.onPostExecute(post);
            if (post != null) {
                mEmailView.setText(post.getBody());
                System.out.print(post);
            }
        }
    };
    asyncTask.execute();
}

-1

Cambie su código como se indica a continuación:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

1
No debería necesitar usar runOnUiThread ya que onPostExecute siempre se ejecuta en el hilo 1 (¿no es así?)
justdan0227
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.