What would be the best way to update my UI? Should I go for Handler or runOnUiThread?
If your Runnable
needs to update UI, post it on runOnUiThread
.
But it's not always possible to post Runnable
on UI Thread.
Think of scenario, where you want need to execute Network/IO operation Or invoke a web service. In this case, you can't post Runnable
to UI Thread. It will throw android.os.NetworkOnMainThreadException
These type of Runnable
should run on different thread like HandlerThread. After completing your operation, you can post result back to UI Thread by using Handler
, which has been associated with UI Thread.
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();
}
}
}