Search code examples
androidandroid-asynctaskontouchlistenertouch-event

Should I use AsyncTask or threads on hold button action?


I have an AsyncTask that writes data to a socket and I wan't to do an onTouch event that holds a button until release. I've actually done that with AsyncTask but the application crashes after writing to the socket. Should I use threads instead or is there a better solution to this problem?

Edit: I get the message "Waiting for a blocking GC Alloc" in the logcat.

OnTouchListener code:

buttonUp.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            while(true){
                if (event.getAction() == MotionEvent.ACTION_DOWN){
                    new moveForward().execute();
                } else if (event.getAction() == MotionEvent.ACTION_UP){
                    break;
                }
            }

            return false;
        }
    });

AsyncTask code:

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

    @Override
    protected Void doInBackground(Void... voids) {
        try {
            MainActivity.client.write('u');

        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
    }
}

Solution

  • You should never run an endless loop on the main UI thread. You can start a task in ACTION_DOWN and end it in ACTION UP. You are starting multiple tasks endlessly. Try this code

        moveForward moveForward;
        buttonUp.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN){
                        moveForward = new moveForward();
                        moveForward.execute();
                    } else if (event.getAction() == MotionEvent.ACTION_UP){
                        moveForward.cancel(true);
                    }
    
                return false;
            }
        });
    
    
        private class moveForward extends AsyncTask<Void, Void, Void>{
    
        @Override
        protected Void doInBackground(Void... voids) {
            while(!isCancelled()) {
                try {
                    MainActivity.client.write('u');
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
             }
    
            return null;
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
        }
    }