I suppose that we can't update any UI view
elements (TextView
, EditText
etc) in any worker thread but in the below example, I am able to update views
from a worker thread, not all the times but only sometimes.
See below example where I'm updating UI elements in worker thread -
public class AndroidBasicThreadActivity extends AppCompatActivity
{
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_basic_thread);
textView = (TextView) findViewById(R.id.textview);
MyAndriodThread myTask = new MyAndriodThread();
Thread t1 = new Thread(myTask, "Bajrang Hudda");
t1.start();
}
}
Here is my worker thread -
class MyAndriodThread implements Runnable
{
@Override
public void run()
{
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
}
Believe me, I won't get any exception saying -
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
And I can see the update UI on emulator.
But if I do any heavy task (sleeping) in worker thread then I got the expected above exception, why it is happening like this? I am a new guy on android multithreading please get me out from this confusion.
If i will change my worker thread to this i will get above exception -
class MyAndriodThread implements Runnable
{
@Override
public void run()
{
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
System.out.println("Child thread completed.");
}
}
And if my UI or main thread is waiting (join()) then i get exact output no exception at all, see this -
MyAndriodThread myTask = new MyAndriodThread();
Thread t1 = new Thread(myTask, "Anhad");
t1.start();
try
{
t1.join();
} catch (InterruptedException e)
{
e.printStackTrace();
}
Update
First I thought it's rendering scheme then i changed my program by using ProgressBar..then i got really unexpected output... Still no exception mean i can update my progress bar in worker thread. See below-
@Override
public void run()
{
for(int i = 1; i<=10; i++)
{
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
activity.progressBar.setProgress(i);
}
}