0

I am totaly new to android and just want to know if it is any working and possible way to update the UI outside the main thread. Just from my code I have listed below I know that from this code; It is not possible at all. But, the thing is I just want to update the UI using another thread. Please help me thanks in advance!

 package com.example.app;

 import java.util.Random;
  import android.os.Bundle;
  import android.app.Activity;
  import android.view.Menu;
 import android.view.View;
  import android.widget.Button;
 import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {
private Button b;
public ImageView I1;
 public ImageView I2;
 public ImageView I3;
public ImageView I4;
public TextView T;
public TextView s;
@Override

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

 I1=new ImageView(this);
 I1=(ImageView) findViewById(R.id.imag1);
 I1.setVisibility(View.INVISIBLE);

 I2=new ImageView(this);
 I2=(ImageView) findViewById(R.id.imag2);
 I2.setVisibility(View.INVISIBLE);

 I3=new ImageView(this);
 I3=(ImageView) findViewById(R.id.imag3);
 I3.setVisibility(View.INVISIBLE);

 I4=new ImageView(this);
 I4=(ImageView) findViewById(R.id.imag4);
 I4.setVisibility(View.INVISIBLE);

 T=(TextView)findViewById(R.id.time);
 s=(TextView)findViewById(R.id.score);

Thread t=new Thread(new MyThread());
t.start();
  }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

private class MyThread implements Runnable{
Random randomGenerator = new Random();
int n;
public void run(){

    while(true){
        n=randomGenerator.nextInt(8);

        if(n==1){
            I1.setVisibility(View.VISIBLE);

        }
        if(n==2){
            I2.setVisibility(View.VISIBLE);
        }

        if(n==3){
            I3.setVisibility(View.VISIBLE);
        }

        if(n==4){
            I4.setVisibility(View.VISIBLE);
        }
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
             e.getStackTrace();
        }
    }

   }




   }
   }
Tech Nerd
  • 822
  • 1
  • 13
  • 39
  • 1
    You should read more about android and multithreading, your code has design flaws. The UI shouldn't be updated by any other thread that the Main thread, this you would know if you had bothered read the documentation. However, android provides tools for you to be able to update the UI from oders being send by other threads but you'll have to read the documentation to figure out how. – Thibault D. May 10 '13 at 13:31
  • 1
    can you please give me the link about that specific documentation? – Tech Nerd May 10 '13 at 13:33
  • 1
    Here, to begin with: [Processes and Thread](http://developer.android.com/guide/components/processes-and-threads.html) – Thibault D. May 10 '13 at 13:45

5 Answers5

3

Use activity.runOnUiThread

Acivity.runOnUiThread(new Runnable() {
    public void run() {
        //something here
    }
});
Arbitur
  • 38,684
  • 22
  • 91
  • 128
mikeswright49
  • 3,381
  • 19
  • 22
2

You can't update UI directly from non-UI thread, but You could communicate with UI thread using Handler object or AsyncTask object. The most convinient way to use AsyncTask:

  1. .doInBackground() method of AsyncTask runs in non-ui thread
  2. .onProgressUpdate() runs in UI thread so could change views
  3. You could use publishProgress() method inside doInBackground() to pass data to .onProgressUpdate.

Sorry if some mistakes in method names. Read http://developer.android.com/guide/components/processes-and-threads.html for details.

Rodion Altshuler
  • 1,713
  • 1
  • 15
  • 31
1

A worker thread never can update main thread because only main thread can render the UI elements (TextView, EditText etc.) and if we try to update for sure we are going to an exception.

myAcitity.runOnUiThread(new Runnable() {
    public void run() {
        //here you can update your UI elements because this code is going to executed by main thread
    }
});

Otherwise you can use post method of View class

myView.post(new Runnable() {
        public void run() {
            //here you can update your UI elements because this code is going to executed by main thread
        }
    });
Bijay
  • 11
  • 3
0

Only main thread can update UI. If your thread want to update UI, use activity.runOnUiThread()

However your action is just queued to run in UI thread(if you are running it not from UI thread), which mean it can update UI a little bit later.

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

Michal Dobrodenka
  • 1,104
  • 8
  • 27
  • But can i use the sleep method to pause the execution. I mean if use sleep inside RunOnUIThread() the main thread will result to be paused and this will create the problem! – Tech Nerd May 10 '13 at 13:35
  • 1
    That is one of main principles of working with UI. Block UI thread for a minimum time, do your logic in background thread and just schedule UI updates with relevant prepared data. – Michal Dobrodenka May 10 '13 at 13:41
0

you have to use an Handler instance and use the post method do add a Runnable inside the queue of the UI Thread. If you are inside an Activity you can use runOnUiThread that is a "shortcut" to do the same thing

Blackbelt
  • 156,034
  • 29
  • 297
  • 305