Android example: Thread, Handler and Looper

Example to run task on background thread using Thread, Handler and Looper:


com.example.androidthreadlooperhandler.MainActivity
package com.example.androidthreadlooperhandler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

Button btn1, btn2;
TextView textInfo;

MyThread myThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.button1);
btn2 = (Button)findViewById(R.id.button2);
textInfo = (TextView)findViewById(R.id.info);

btn1.setOnClickListener(btnOnClickListener);
btn2.setOnClickListener(btnOnClickListener);

myThread = new MyThread();
myThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

//stop and quit the background Thread
myThread.handler.getLooper().quit();
}

View.OnClickListener btnOnClickListener =
new View.OnClickListener(){

@Override
public void onClick(View v) {
if(myThread.handler != null){
Message message;
if(v==btn1){
message = myThread.handler.obtainMessage(MyThread.MSG1);
}else{
message = myThread.handler.obtainMessage(MyThread.MSG2);
}
myThread.handler.sendMessage(message);
}
}
};

private class MyThread extends Thread{

static final int MSG1 = 1;
static final int MSG2 = 2;

public Handler handler;

public void run(){
Looper.prepare();
handler = new MyHandler();
Looper.loop();
}

private class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
// ...Run in background

int what = msg.what;
switch (what){
case MSG1:

//doing something...
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

runOnUiThread(new Runnable() {
@Override
public void run() {
textInfo.setText("Message 1");
}
});

break;
case MSG2:

//doing something...
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

runOnUiThread(new Runnable() {
@Override
public void run() {
textInfo.setText("Message 2");
}
});

break;

}
}
}
}
}


layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"/>

<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2"/>

<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</LinearLayout>



In this example, background thread update UI (TextView) via runOnUiThread(). It's modified in next example to implement Handlers in both UI and background thread, to pass data in both direction via Handler/Message.