user2950911
user2950911

Reputation: 933

Android Refresh TextView from Thread

I know there are already quite a number of discussions about this, but none of what I found could clear my confusion.
I'm using the Android SDK for the first time and my Java Skills are rather average.

I have the following Problem:
From my MainActivity - OnCreate() fct. I start a thread (Receiver), receiving data from a SocketStream. This thread shall refresh a TextView-Element on the GUI when new data was read from the stream.
What is a simple but proper way to do so? I read something about ASyncTask, but did not understand how to implement it.

public class MainActivity extends Activity 
{
    ExecutorService myExecutor;

    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println("this is a test"); System.out.flush();

        try 
        {
            myExecutor = Executors.newCachedThreadPool();
            myExecutor.execute(Receiver.getInstance());
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

...

public class Receiver implements Runnable  
{  
[...]  
    public void run()  
    {  
        while (true)  
        {  
            //blocking system-io-call to read data from socket..  
            //extract information  
            // *** update textView *** ??  
        }  
    }  
}  

Upvotes: 0

Views: 4411

Answers (3)

javad
javad

Reputation: 835

this is a example:

create Counter class :

public class Counter implements Runnable
{
    private ICounterEvents listener;
    public static Thread OBJ_THREAD = null;

    public Counter()
    {       
        OBJ_THREAD = new Thread(this);          
    }

    public void setCountListener(ICounterEvents listener)
    {
        this.listener = listener;
    }

    public void start()
    {       
        OBJ_THREAD.start();
    }                       

    @Override
    public void run() 
    {
        for(int i = 0; i < 100; i++)
        {
            try 
            {
                Thread.sleep(1000);
            } 
            catch (InterruptedException e) 
            {               
                e.printStackTrace();
            }

            Message msg = Message.obtain();
            msg.obj = i;            
            this.handler.sendMessage(msg);
        }
    }

    private Handler handler = 
            new Handler()
            {
                @Override
                public void handleMessage(Message msg)
                {
                    if(Counter.this.listener != null)
                    {
                        int value = (Integer)msg.obj;
                        Counter.this.listener.countChanged(value);
                    }
                }
            };
}

and create a interface class:

public interface ICounterEvents 
{
    public void countChanged(int value);
}

and than in your main layout create a textview and a button, and use this code in onCreate method in MainActivity:

public class MainActivity extends Activity implements ICounterEvents, OnClickListener
{
    private TextView txtCounter;
    private Button btnStart;
    private Counter counter;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.setupViews();
    }

    private void setupViews() 
    {
        this.counter = new Counter();
        this.counter.setCountListener(this);

        this.txtCounter = (TextView)findViewById(R.id.txtCount);
        this.btnStart = (Button)findViewById(R.id.btnStart);    

        this.btnStart.setOnClickListener(this);
    }   

    @Override
    public void onClick(View v) 
    {       
        this.counter.start();
    }

    public void countChanged(int value)
    {
        try 
        {
            this.txtCounter.setText(value + "");
        } 
        catch (Exception e) 
        {           

        }
    }   
}

Upvotes: 1

Abhishek V
Abhishek V

Reputation: 12526

You can use runOnUiThread

public class Receiver implements Runnable  
{  
[...]  
    public void run()  
    {  
        while (true)  
        {  
            //blocking system-io-call to read data from socket..  
            //extract information  

         runOnUiThread(new Runnable() {
                public void run() {
                     // *** update textView *** ??  
                }
            });
    }  
}  
}  

Upvotes: 2

You can implement handler in GUI thread to change GUI (in MainActivity in your case):

public Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //refresh textview
        }
    };

and than call it from another threads

activity.handler.sendEmptyMessage(what);

You can write your own constructor for Receiver:

public class Receiver implements Runnable  
{  
[...]  
    MainActivity activity;
    public Receiver(MainActivity activity){
        this.activity = activity;
    }  


    public void run()  
    {  
        while (true)  
        {  
            //blocking system-io-call to read data from socket..  
            //extract information  
            // *** update textView *** ??  
           activity.handler.sendEmptyMessage(0);
        }  
    }  
}  

Upvotes: 2

Related Questions