2011-11-18 28 views
6

Estoy desarrollando una aplicación para Android, y tengo un botón que inicia/pausa cierto proceso de simulación. Mientras se está ejecutando este proceso, necesito sacar algunos datos de él en tiempo real. Pero cuando creo un nuevo hilo para la simulación, no puedo acceder a las vistas (dejar que sea TextView) de este hilo, porque solo se puede acceder desde el hilo donde se crearon. Por otro lado, es necesario un nuevo hilo porque, de lo contrario, el usuario no podría hacer nada mientras se ejecuta la simulación (por ejemplo, presione algunos otros botones). Crear un nuevo servicio también requiere crear un nuevo hilo en este caso. ¿Cómo debo resolver este problema?Accediendo a vistas desde otro hilo (Android)

+0

¿Ha revisado el [ 'AsyncTask'] (http: // desarrollador .android.com/reference/android/os/AsyncTask.html) clase? Es una clase de utilidad que te ayuda a crear un hilo diferente fácilmente y actualizar los elementos de la interfaz de usuario en consecuencia. Podría usar sus métodos 'publishProgress()' y 'onProgressUpdate()' en este caso. –

Respuesta

5

Puede manejar la situación de muchas maneras,

  1. intenta utilizar AsyncTask en este, su trabajo fondo hecho en doInBackGround() método, y la interfaz de usuario no bloqueará y también se puede acceda a las vistas de la actividad desde donde llama a AsyncTask por su contexto a través de publishProgress() y onProgressUpdate().

  2. Si está utilizando un simple hilo a continuación, utilizando Handler o mensaje o runOnUiThread puede actualizar la vista del hilo principal.

pero, in your way I think AsyncTask is best for you.

2

Puede resolver el problema con android.os.Handler. La instancia del manejador está vinculada al hilo que lo crea, puede colocar Runnables en él y los ejecutará en el hilo al que está vinculado. Por ejemplo:

import android.os.Handler; 
import android.widget.TextView; 

public class MyActivity extends Activity { 
    private Handler uiHandler; 
    private TextView simulationStatus; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    ... 
    uiHandler = new Handler(); 
    ... 
    simulationStatus = (TextView) findViewById(R.id.simulationStatus); 
    ... 
    } 

    // This method is to be executed on the simulation thread. 
    public void simulate() { 
    ... 
    final String simulationStatusText = ...; 
    ... 
    uiHandler.post(new Runnable() { 
     @Override 
     public void run() { 
     // This is run on the UI thread. 
     simulationStatus.setText(simulationStatusText); 
     ... 
     } 
    }); 
    } 

    ... 
} 

También puede usar AsyncTask. Ver el enlace por ejemplo.

1

Pase la actividad a su hilo y úselo desde dentro para acceder a sus vistas.

// from your activity: 
myExternalThread = new MyCustomCode(this); // <-- activity passed 

// your "simulation process" constructor: 
public MyCustomCode(Activity parent) { 
    this.parent = parent; 
} 

// and when you want to access views: 
parent.runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     parent.findViewById(R.id.text_view); 
     ... do something to your UI ... 
    } 
}); 

Mi forma preferida de la creación de estas tareas externas es utilizar AsyncTask (entonces usted no tiene que preocuparse por runOnUiThread, entre otros beneficios). No sé si se aplica a su caso, pero debería verificarlo.

+0

¿Por qué el -1?¿Alguna explicación? – Guillaume

1

usted tiene que almacenar los datos que se desean Qué muestran en una var pública y deje que su rosca llamar a un Ejecutable a través Handler.post (ejecutable) El código en el plazo() el método de Runnable puede acceder a la vista de texto

2

Se puede acceder a ellas, pero solo de lectura. Lo que quiere decir es que quiere desencadenar cambios de un hilo en las vistas. Desde el subproceso de trabajo (no UI) estos cambios no se pueden desencadenar, debe usar .runOnUiThread() o usar Handlers. Utilizar estos términos en el punto en el que desea mostrar algo, por ejemplo, actualizar el TextView en .runOnUiThread(),

Ejemplo:

myThread = new Thread() 
     { 

      @Override 
      public void run() { 
       //yourOperation 
       MyActivity.this.runOnUiThread(new Runnable(){ 

        @Override 
        public void run() { 
         if(e!=null) 
         { 
          myTextView.setText("something"); 
         } 

        }}); 
       super.run(); 
      } 
     }; 
     myThread.start(); 
+0

¿es realmente posible leer solo una vista de un hilo que no sea de la interfaz de usuario como usted mencionó? Estoy interesado en leer un mapa de bits fuera de una vista usando Bitmap drawingCache = view.getDrawingCache() pero sigo recibiendo la excepción: CalledFromWrongThreadException: solo el hilo original que creó una jerarquía de vista puede tocar sus vistas. – Giorgio

Cuestiones relacionadas