Error Only the original thread that created a view of the hierarchy can touch its views. on Android

1

After Android-Studio warned me that there is too much load on the main thread.

  

Skipped 113 frames: the application may be doing too much work on its main thread

I have created a runnable to launch a thread with some processes:

new Thread(new Runnable() {
    @Override
    public void run() {
       UpdateUI(); //Actualiza datos de la Interfaz de usuario
    }
}

But it returns the error:

  

Only the original thread that created a view of the hierarchy can touch its views.

I searched for SO and can throw a thread

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
       //Cambiar controles
    }
});

But since I have to do a lot of checks or a thread is executed at the same time, it returns the main thread overload. I even notice that the side menu slows down when closing.

How do you make a thread but be able to access the elements of the interface in order to modify your data or states?

    
asked by Webserveis 10.05.2017 в 15:14
source

1 answer

3

To fix the error:

  

Only the original thread that created a view of the hierarchy can touch its views.

You can use runOnUIThread or AsyncTask depending on the task to be performed, if it requires a lot of process directly to AsyncTask

runOnUiThread to run a thread with access to the elements of the interface:

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
       //Cambiar controles
    }
});

AsyncTask

To execute a task that consumes a lot, and keep the user informed of the process and at the end refresh the UI:

  • In doInBackground the task

The following allow you to interact with the elements of the UI

  • In onProgressUpdate to report its elapsed time
  • In onPostExecute at the end of refreshing the UI.

Example of an AsyncTask:

private class myUpdateAsyncTask extends AsyncTask<Intent, Integer, Boolean> {

        private Context mContext;
        private String title;

        public myUpdateAsyncTask (Context context) {
            this.mContext = context;
        }


        @Override
        protected Boolean doInBackground(Intent... intents) {
            //@Todo Tarea a procesar
            title = "soy un titulo asyncTask"
            publishProgress(1); //Para mandar control para actualizar la UI
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            //@Todo values[0] para obtener el código de control, actualizar la UI
            if (values[0]==1) textView.setText(title)
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);

            if (result) {
                //@Todo AsyncTask finalizado
            }
        }

    }

Some Tips

  • Look to create control variables, if more than one process needs to obtain value from the same function.
  • Only update the elements of the interface that require it, using numerical control variables can be predetermine which affect.
answered by 10.05.2017 / 22:06
source