我要做的是修改一个线程内的全局ArrayList,并在我的Thread之外修改这个ArrayList。
这是我的代码,它可以工作但是当我从外面读取我的ArrayList时,它有一个正确的大小但是这个ArrayList中的所有元素都是最后添加的,我的意思是如果最后一个元素有pollingCode,pollingType,polling Value = 0 ,数组中的所有元素都具有相同的值。
有人知道为什么会这样吗?
public abstract class OverlayView extends RelativeLayout {
protected ArrayList<InputEvent> eventList = new ArrayList<InputEvent>();
public void StartEventMonitor() {
Thread b = new Thread(new Runnable() {
public void run() {
InputEvent ie= new InputEvent();
while (m_bMonitorOn) {
for (InputDevice idev:events.m_Devs) {
// Open more devices to see their messages
int pollingEvent = idev.getPollingEvent();
int pollingType=idev.getSuccessfulPollingType();
int pollingCode=idev.getSuccessfulPollingCode();
int pollingValue=idev.getSuccessfulPollingValue();
final String line =/* idev.getName()+
": " +*/ idev.getSuccessfulPollingType()+
" " + idev.getSuccessfulPollingCode() +
" " + idev.getSuccessfulPollingValue() +
"\n";
Log.d(LT, "Event:"+line);
ie.setCode(pollingCode);
ie.setType(pollingType);
ie.setValue(pollingValue);
eventList.add(ie);
}
}
}
}
});
b.start();
}
}
答案 0 :(得分:2)
您是否尝试在循环中创建新的InputEvent。您只有一个即添加列表,只需更新InputEvent
上的值:
InputEvent ie= new InputEvent();
while (m_bMonitorOn) {
ie= new InputEvent();
...
答案 1 :(得分:2)
这只是一个与多线程无关的FYI。
您正在重复使用相同的InputEvent对象。所以你调用setCode
调用同一个InputEvent的setCode方法。添加只是每次都会添加相同的IE实例。
例如,尝试(假设列表大小> 1)
if(eventList.get(0) == eventList.get(1)){
//re using the same object
}
您应该在for循环中移动InputEvent的创建分配。
答案 2 :(得分:2)
不在所有细节中研究代码:您的列表不是线程安全的。我建议您使用类似ArrayBlockingQueue的内容来共享线程之间的事件。这将消除重大问题,无论如何都是正确的事情。
答案 3 :(得分:0)
你有2个错误:
首先,改变:
protected ArrayList<InputEvent> eventList = new ArrayList<InputEvent>();
到
protected final List<InputEvent> eventList =
Collections.synchronizedList(new ArrayList<InputEvent>());
这将使得从List线程安全地添加和删除项目。现在我们需要修复添加项目的问题。对于每个事件,您都需要新的InputEvent实例。所以按照以下方式改变你的循环:
public void run() {
while (m_bMonitorOn) {
for (InputDevice idev:events.m_Devs) {
InputEvent ie= new InputEvent();
...
eventList.add(ie);
}
}
}