How do I stop a class that I inherited from AsyncTask in Android Studio

0

Hi, I'm programming a button in Android Studio and I want you to send me a message after the button is pressed for 2 seconds, but when my counter reaches 2 and I want to show a Toast the application stops me. I create a Boolean variable to know if the button is pressed or not and a counter to know how many seconds it has been pressed:

boolean estaPresionado = false;
int contador = 0;

Here I assign an event to my button:

btnAlerta1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(getContext(), "Mensaje no enviado", Toast.LENGTH_SHORT).show();
            btnAlerta1.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    switch (motionEvent.getAction()) {

                        case MotionEvent.ACTION_DOWN:

                            if (!estaPresionado) {
                                estaPresionado = true;
                                new EnviarContadorTarea().execute();
                            }
                            break;
                        case MotionEvent.ACTION_UP:
                            estaPresionado = false;

                    }
                    return true;
                }
            });
        }
    });

Command to call creating an instance of the SendTapeCounter class, which is the following:

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

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

        while(estaPresionado) {
            int con = AumentarContador();
            if (con == 2){
                mostrarMensaje();
                contador = 0;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

There, I'll call the repeating method to increase the counter:

private int AumentarContador(){

        contador = contador+1;
        Log.i("Contador","contador: "+contador);

        return contador;
    }

And finally when the counter reaches 2 commands to call the method showMessage:

private void mostrarMensaje() {

    Toast.makeText(getContext(), "Mensaje enviado", Toast.LENGTH_SHORT).show();
}

But when I press the button and it reaches 2 it stops unexpectedly and sends me this error:

java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:309)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:209)
    at android.os.Handler.<init>(Handler.java:123)
    at android.widget.Toast$TN.<init>(Toast.java:350)
    at android.widget.Toast.<init>(Toast.java:106)
    at android.widget.Toast.makeText(Toast.java:264)
    
asked by Cristian Ruiz 19.10.2018 в 00:13
source

1 answer

0

The issue is that you are trying to send a Toast to the screen in a Thread that is not the UI thread (user interface). Any update to the user interface has to be done in that thread.

This can be done with Activity#runOnUiThread , but since you are using AsyncTask you can also do it directly with methods of that class.

With AsyncTask you can use publishProgress() , and onProgressUpdate() , which run in UI thread.

@Override
protected Void doInBackground(Void... arg0) {
    boolean terminar = false;
    while(estaPresionado && !terminar) {
        int con = AumentarContador();
        if (con == 2){
            publishProgress();
            terminar = true;
            contador = 0;
            continue;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return null;
}

@Override
protected void onProgressUpdate(Void... progress){
      mostrarMensaje();  
}

Note: Keep in mind that the data type of the progress is defined by the media type in the AsyncTask definition: AsyncTask<Params, Progress, Result>

    
answered by 19.10.2018 / 06:30
source