Reputation: 1721
I have scoured the web to find definite examples of this but so far couldn't find one which I could have applied to my project.
I'm trying to create a worker-thread which is run every 100ms. It then should update UI with results. After some research I decided that I probably should use Handlers to manage the UI-updating. I came to this solution:
My activity's Handler:
private final Handler handler = new Handler() {
public void handleMessage(Message msg) {
String aResponse = msg.getData().getString("message");
if ((null != aResponse)) {
// ALERT MESSAGE
Log.v("udppacket", "UDP message!");
if (msg.obj != null)
{
ManagerUdpPacket p = (ManagerUdpPacket) msg.obj;
operatorListFragment.updateContent((int) p.getOperationTime());
}
}
else
{
}
}
};
My other class which has the worker-thread:
public class ManagerUdpReceiver
{
private int minPort = 1234;
private int maxPort = 1240;
private ArrayList<PortListener> portList;
private Handler handler;
private Thread portThread;
private int queryInterval = 100;
private boolean stop = false;
public ManagerUdpReceiver(int minport, int maxport, Handler handler, int queryInterval)
{
minPort = minport;
maxPort = maxport;
this.handler = handler;
this.queryInterval = queryInterval;
//create port listeners from given range and start their threads
start();
}
private void start()
{
stop = false;
// Create Inner Thread Class
portThread = new Thread(new Runnable()
{
// After call for background.start this run method call
public void run()
{
if (portList == null)
{
portList = new ArrayList<PortListener>();
for (int i = minPort; i < maxPort; i++)
{
portList.add(new PortListener(i));
}
}
if (!stop)
{
ManagerUdpPacket p = portList.get(0).receive();
threadMsg("moi", p);
//mHandler.postDelayed(this, queryInterval);
}
else
{
//stop execution and close ports
for (int i = 0; i < portList.size(); i++)
{
portList.get(i).close();
}
}
}
//send message to the handler
private void threadMsg(String msg, ManagerUdpPacket p)
{
if (!msg.equals(null) && !msg.equals(""))
{
Message msgObj = handler.obtainMessage();
//msgObj.obj = p;
Bundle b = new Bundle();
b.putString("message", msg);
msgObj.setData(b);
handler.sendMessage(msgObj);
}
}
});
// Start Thread
portThread.start();
}
public void close()
{
stop = true;
}
}
When I run the program I get exception about running networking code in UI-thread. Now, the worker-thread should receive and process UDP-packets. However, the code for that is inside of the portThread thread! I suppose that handler.postDelayed(this, queryInterval); which I use to loop the thread in every 100ms somehow causes the next cycle to be run in UI-thread instead of my worker-thread.
So my question is what I'm doing wrong here and how to fix it? Or alternatively, how to get the looping work correctly in every 100ms? I'm also not sure where to place the Handler, since I have seen examples where it is inside Activity and inside the worker-thread.
Upvotes: 0
Views: 732
Reputation: 344
dont really understand purpose of handlers. Why you dont just prepare data on backround thread and than use myActivity.runOnUIThread()
to run your updateContent() method? Maybe p.getOperationTime()
is considered network operation, try to save this value to some variable in background thread and than publish it by UI thread.
Upvotes: 0
Reputation: 1721
Ok, I think I got it working though I'm not satisfied with it and so leaving this unchecked.
Basically I ended up using TimerTask to run my code every 100ms and notifying UI-thread via Handler. I'm not really sure if this is best choice (I have heard that Timers aren't that great) but seems to work:
dataStreamTimer = new Timer();
dataStreamTask = new TimerTask()
{
public void run()
{
if (portList == null)
{
portList = new ArrayList<PortListener>();
for (int i = minPort; i < maxPort; i++)
{
portList.add(new PortListener(i));
}
}
if (!stop)
{
ManagerUdpPacket p = portList.get(0).receive();
threadMsg("moi", p);
//handler.postDelayed(this, queryInterval);
//stop thread until next query
try {
synchronized(this){
this.wait(queryInterval);
}
} catch (InterruptedException e) {
Log.e("ERR", "InterruptedException in TimerTask.run");
}
}
else
{
//execution has been stopped, clear data:
//stop execution and close ports
for (int i = 0; i < portList.size(); i++)
{
portList.get(i).close();
}
}
}
Upvotes: 1