Sometimes updating progress bar on main thread from worker thread doesn't crash the android application

Viewed 1285

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();
                }
            }
        }
    }
}
1 Answers
Related