¿Cuál sería la mejor manera de actualizar mi UI? ¿Debería ir a Handler o runOnUiThread?
Si su Runnable
necesita actualizar su IU, publíquelo en runOnUiThread
.
Pero no siempre es posible publicar Runnable
en UI Thread.
Piense en el escenario, donde necesita ejecutar Operación de red/IO O invoque un servicio web. En este caso, no puede publicar Runnable
en UI Thread. Se lanzará android.os.NetworkOnMainThreadException
Este tipo de Runnable
debe ejecutarse en diferentes hilos como HandlerThread. Después de completar su operación, puede enviar el resultado de vuelta al Subproceso UI utilizando Handler
, que se ha asociado con Subproceso UI.
public void onClick(View view) {
// onClick on some UI control, perform Network or IO operation
/* Create HandlerThread to run Network or IO operations */
HandlerThread handlerThread = new HandlerThread("NetworkOperation");
handlerThread.start();
/* Create a Handler for HandlerThread to post Runnable object */
Handler requestHandler = new Handler(handlerThread.getLooper());
/* Create one Handler on UI Thread to process message posted by different thread */
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
requestHandler.post(r1);
requestHandler.post(r2);
}
class NetworkRunnable implements Runnable{
String url;
Handler uiHandler;
public NetworkRunnable(String url,Handler uiHandler){
this.url = url;
this.uiHandler=uiHandler;
}
public void run(){
try {
Log.d("Runnable", "Before IO call");
URL page = new URL(url);
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ((line = buff.readLine()) != null) {
text.append(line + "\n");
}
Log.d("Runnable", "After IO call:"+ text.toString());
Message msg = new Message();
msg.obj = text.toString();
/* Send result back to UI Thread Handler */
uiHandler.sendMessage(msg);
} catch (Exception err) {
err.printStackTrace();
}
}
}
'runOnUiThread' es solo un atajo para publicar un' Runnable' en un 'Handler'. 'Handler' es la base de cada recurso (?) De comunicación entre hilos definido por Android (por ejemplo' 'onPostExecute' de AsyncTask' utiliza un' Handler' para entregar el resultado de 'doInBackground'). – zapl