我已经在网络上寻找了明确的例子,但到目前为止还没有找到一个我可以应用到我的项目中的例子。
我正在尝试创建一个每100ms运行一次的工作线程。然后,它应该用结果更新UI。经过一些研究后,我决定我可能应该使用处理程序来管理UI更新。我得到了这样的解决方案:
我的活动处理程序:
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
{
}
}
};我的另一个类有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;
}
}当我运行程序时,我得到异常运行网络代码在UI-thread。现在,工作线程应该接收和处理UDP数据包。但是,它的代码在portThread线程内部!我假设我用来每隔100ms循环线程的handler.postDelayed(this,queryInterval)会导致下一个周期在UI-thread中运行,而不是在我的worker-thread中运行。
所以我的问题是,我在这里做错了什么,以及如何修复它?或者,如何让循环在每100毫秒内正确工作?我也不确定该把Handler放在哪里,因为我已经看到过它在Activity和worker-thread内部的例子。
发布于 2013-08-01 18:32:21
好的,我想我得到了它的工作,尽管我对它不满意,所以不检查它。
基本上,我最终使用TimerTask每隔100ms运行一次代码,并通过处理程序通知UI-thread。我真的不确定这是不是最好的选择(我听说计时器不是那么好),但似乎是有效的:
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();
}
}
}发布于 2013-08-01 18:33:20
并不真正理解处理程序的目的。为什么不在后台线程上准备数据,然后使用myActivity.runOnUIThread()来运行updateContent()方法呢?也许p.getOperationTime()被认为是网络操作,尝试将这个值保存到后台线程的某个变量中,然后通过UI线程发布它。
https://stackoverflow.com/questions/17990813
复制相似问题