I have an example of android app to update progressbar on main thread from worker thread using handler, it's working fine but when i try to update progressbar inside worker thread without handler, it still works, though it's supposed to crash. Because according to Android documentation UI thread is not safe and must not be accessed from worker thread directly.
***Update Sorry i put the wrong activity_main.xml. This is the correct one i am using.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.riaz.handlerexample.MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
</android.support.constraint.ConstraintLayout>
***Update
Here is the activity_main.xml. ** Update. Wrong layout file, Please ignore
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:max="10"
android:padding="4dip" >
</ProgressBar>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Progress percentage"
android:textSize="16sp"/>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="startProgress"
android:text="Start"
android:textSize="16sp"/>
</LinearLayout>
Java code
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Thread thread; // work as a background thread
Handler handler; // handle main thread messages from worker thread
ProgressBar progressBar; // on UI/main thread
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
Toast.makeText(MainActivity.this, "OnCreate Thread Name = "
+Thread.currentThread().getName(),
Toast.LENGTH_LONG).show(); // Thread Name = main
System.out.println("OnCreate Method,Thread Name= " +
Thread.currentThread().getName()); // Thread Name = main
thread = new Thread( new MyThread());// creating a background thread
thread.start(); // starting the background thread. it will execute run() method in
// MyThread class
handler = new Handler(){ //handles the incoming messages from background thread
@Override // receives message from worker thread sendmessage(message)
public void handleMessage(Message msg) {
System.out.println("Inside Handler,Thread Name= " +
Thread.currentThread().getName()); //thread Name = main
// progressBar.setProgress(msg.arg1);
}
};
}
// this is background / worker thread
class MyThread implements Runnable
{
@Override
public void run() {
Toast.makeText(MainActivity.this, "Worker Thread Name = "
+Thread.currentThread().getName(),
Toast.LENGTH_LONG).show(); // Thread Name = main
for (int i=0; i<100;i++)
{
System.out.println("Worker Thread,Thread Name= " +
Thread.currentThread().getName());
// Message message = Message.obtain(); // blank empty message
// message.arg1 = i;
// handler.sendMessage(message); //calling main thread
progressBar.setProgress(i);
//create delay to see the progress on progressbar
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}