2011-05-02 12 views
5

Tengo un método updateFoo() de una actividad llamada tanto desde un subproceso de Manejador cada 5 segundos como desde un botón cuando el usuario desea presionarlo ... actualizarDe manera actualizo la interfaz de mi actividad. .. para que este método sea seguro, lo declare "sincronizado" ... ¿Es así?Hacer que un método de actividad android sea seguro

Respuesta

1

Marcado un método synchronized es una manera para que sea seguro ante los threads - básicamente lo hace de manera que sólo un hilo puede estar en el método en un momento dado.

Sin embargo, eso podría no ser la opción mejor porque si updateFoo() hace algunas operaciones de larga ejecución, el hilo de interfaz de usuario podría colgar (es decir. La prensa botón puede quedar atrapado esperando para entrar en [y ejecutar] updateFoo().

un método más granular sería utilizar cerraduras, o algunas de las otras opciones de encadenamiento de Java Si publica el código a su método, que nos gustaría poder encontrar una solución mejor

0

Si usa la concurrencia de paso de mensajes, no debería preocuparse demasiado por los conflictos de concurrencia. Para hacer esto, pasaría un objeto inmutable para iniciar el hilo, el hilo no leería ni escribiría en ninguna memoria compartida fuera del hilo, y el hilo devolvería un objeto inmutable.

Si utiliza la comunicación de memoria compartida, en mi humilde opinión, simplemente declarar su método sincronizado puede o no ser suficiente para ser seguro para subprocesos. Si el método IN TURN accede a la memoria compartida que no es segura para subprocesos, atómica, etc., podría haber conflictos de concurrencia.

0

Gracias a todos por las respuestas :) Probé este código, más simple que el proyecto que estoy edificio:

package provadroid.prova; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

public class AndroidSynch extends Activity { 

    private TextView text_to_view; 
    private Button change_text; 


    private static final Handler handler = new Handler(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     this.change_text = (Button)this.findViewById(R.id.change_button); 
     this.text_to_view = (TextView)this.findViewById(R.id.text_to_view); 

     this.change_text.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) 
      { 
       AndroidSynch.this.updateText(" Button "); 
      } 
     }); 

     doTheAutoRefresh(5000); 

    } 

    synchronized void updateText(String str) 
    { 
     this.text_to_view.setText(this.text_to_view.getText() + str); 
    } 

    void doTheAutoRefresh(long time) { 
     handler.removeMessages(0); 
     handler.postDelayed(new Runnable() { 

      @Override 
      public void run() { 
       AndroidSynch.this.updateText(" Handler "); 
       AndroidSynch.this.doTheAutoRefresh(5000); 
      } 

     }, time); 
    } 


} 

Un manejador de fondo ejecuta en segundo plano cada 5 segundos, después de que la actualización de la TextView .. El botón actualiza la vista de texto también ...

Todo parece funcionar bien tanto con sincronización en la función update_text como sin ella ... Supongo que eso sucede porque update_text funciona en la UI para que el manejador tenga acceso exclusivo y espere si alguien está llamando a update_text..Pero si la función no funciona en la interfaz de usuario y es invocada por el controlador y por un botón u otro controlador, debería declararlo sincronizado, ¿verdad?

Cuestiones relacionadas