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:
¿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
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
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
})
“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?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
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
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