runOnUiThread en fragmento

5 minutos de lectura

avatar de usuario
Tai dao

Estoy tratando de convertir una actividad en fragmento. La marca de error en runOnUiThread. en el pasado:

GoogleActivityV2 se extiende desde Actividad. runOnUiThread en la clase ExecuteTask. clase ExecuteTask anidada en la actividad.

(Corre bien) ahora:

GoogleActivityV2 se extiende desde Fragment. runOnUiThread en la clase ExecuteTask. clase ExecuteTask anidada en la actividad. (Error en runOnUiThread)

aquí está mi código

public class GoogleActivityV2 extends SherlockMapFragment implements OnMapClickListener , OnMapLongClickListener , OnCameraChangeListener , TextWatcher {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.activity_googlev2, container, false);
        Init();
        adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line);
        textView = (AutoCompleteTextView) getView().findViewById(R.id.autoCompleteTextView1);
        return rootView;
    }

    public void onCameraChange(CameraPosition arg0){
        // TODO Auto-generated method stub
    }

    public void onMapLongClick(LatLng arg0){
        llLoc = arg0;
        stCommand = "onTouchEvent";
        lp = new ExecuteTask();
        lp.execute();
    }

    public void onMapClick(LatLng arg0){
        // TODO Auto-generated method stub
    }

    class ExecuteTask extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            if(stCommand.compareTo("AutoCompleteTextView") != 0) {
                pDialog = new ProgressDialog(getActivity());
                pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading ..."));
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
                pDialog.show();
            }
        }

        protected String doInBackground(String ... args){
            do something
            return null;
        }

        @Override
        protected void onPostExecute(String file_url){
            if(stCommand.compareTo("AutoCompleteTextView") != 0) pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run(){
                    do something
                }
            });
        }
    }
    public void afterTextChanged(Editable s){
        // TODO Auto-generated method stub
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after){
        // TODO Auto-generated method stub
    }

    public void onTextChanged(CharSequence s, int start, int before, int count){
        // TODO Auto-generated method stub
    }
}

el error dice:
Error de eclipse

¿Cómo puedo solucionar este error?

  • El código que escribe dentro de onPostExecute ya se ejecuta dentro del hilo principal. Por otro lado, no necesita invocar runOnUiThread().

    – rciovati

    7 mayo 2013 a las 17:35


  • @rciovati “hacer algo” dentro y fuera de PostExecute son diferentes

    – Tai Dao

    7 mayo 2013 a las 17:37

avatar de usuario
bclymer

Prueba esto: getActivity().runOnUiThread(new Runnable...

Eso es porque:

1) lo implícito this en tu llamada a runOnUiThread se refiere a AsyncTask, no a su fragmento.

2) Fragment no tiene runOnUiThread.

Sin embargo, Activity lo hace.

Tenga en cuenta que Activity simplemente ejecuta el Runnable si ya está en el hilo principal, de lo contrario, utiliza un Handler. Puedes implementar un Handler en su fragmento si no quiere preocuparse por el contexto de thisen realidad es muy fácil:

// A class instance
private Handler mHandler = new Handler(Looper.getMainLooper());

// anywhere else in your code
mHandler.post(<your runnable>);
// ^ this will always be run on the next run loop on the main thread.

EDITAR: @rciovati tiene razón, estás en onPostExecuteeso ya está en el hilo principal.

  • Algunas veces getActivity().runOnUiThread resulta en NullPointerException. ¿Podrías explicar?

    – Vadiraj Purohit

    27/04/2016 a las 19:46

  • @developer1011 eso ocurrirá cuando el fragmento se haya separado de la actividad. Esto es común en las tareas asíncronas, porque la actividad podría haberse destruido durante la operación de ejecución prolongada, por lo que ya no existe para get. Siempre verifique si es nulo primero.

    – bclymer

    27/04/2016 a las 21:15

  • Gracias. yo rodeé getActivity().runOnUiThread con if (isAdded()) y funciona bien

    – Vadiraj Purohit

    29/04/2016 a las 19:54

  • @bclymer, dada esta respuesta, es la referencia de facto en Google para el subproceso de interfaz de usuario en fragmentos, ¡sería bueno tener más detalles sobre la última sección (cómo implementar un controlador que haga el mismo trabajo)!

    – LS97

    10 de abril de 2018 a las 11:36

avatar de usuario
Gibolt

Usar una función de extensión de Kotlin

fun Fragment?.runOnUiThread(action: () -> Unit) {
    this ?: return
    if (!isAdded) return // Fragment not attached to an Activity
    activity?.runOnUiThread(action)
}

Entonces, en cualquier Fragment solo puedes llamar runOnUiThread. Esto mantiene las llamadas consistentes entre actividades y fragmentos.

runOnUiThread {
    // Call your code here
}

NOTA: Si Fragment ya no está unido a un Activityno se llamará a la devolución de llamada y no se lanzará ninguna excepción

Si desea acceder a este estilo desde cualquier lugar, puede agregar un objeto común e importar el método:

object ThreadUtil {
    private val handler = Handler(Looper.getMainLooper())

    fun runOnUiThread(action: () -> Unit) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            handler.post(action)
        } else {
            action.invoke()
        }
    }
}

  • Me encantan las funciones de las extensiones de Kotlin.

    – Ohhh Ese Varun

    17 abr 2020 a las 21:26

Para Kotlin en fragmento solo haz esto

activity?.runOnUiThread(Runnable {
        //on main thread
    })

avatar de usuario
Ripdaman Singh

En Xamarin.Android

Para Fragmento:

this.Activity.RunOnUiThread(() => { yourtextbox.Text="Hello"; });

Por Actividad:

RunOnUiThread(() => { yourtextbox.Text="Hello"; });

Feliz codificación 🙂

Usé esto para obtener Fecha y Hora en un fragmento.

private Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View root = inflater.inflate(R.layout.fragment_head_screen, container, false);

    dateTextView =  root.findViewById(R.id.dateView);
    hourTv = root.findViewById(R.id.hourView);

        Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(1000);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            //Calendario para obtener fecha & hora
                            Date currentTime = Calendar.getInstance().getTime();
                            SimpleDateFormat date_sdf = new SimpleDateFormat("dd/MM/yyyy");
                            SimpleDateFormat hour_sdf = new SimpleDateFormat("HH:mm a");

                            String currentDate = date_sdf.format(currentTime);
                            String currentHour = hour_sdf.format(currentTime);

                            dateTextView.setText(currentDate);
                            hourTv.setText(currentHour);
                        }
                    });
                }
            } catch (InterruptedException e) {
                Log.v("InterruptedException", e.getMessage());
            }
        }
    };
}

avatar de usuario
Yawad Zeb

También puede publicar ejecutable usando la vista desde cualquier otro hilo. Pero asegúrese de que la vista no sea nula:

 tView.post(new Runnable() {
                    @Override
                    public void run() {
                        tView.setText("Success");
                    }
                });

Según la Documentación:

“publicación booleana (acción ejecutable) Hace que el ejecutable se agregue a la cola de mensajes. El ejecutable se ejecutará en el subproceso de la interfaz de usuario”.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad