Reputation: 933
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
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
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
Reputation: 5672
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