2

我想要做的是在一个线程内修改全局 ArrayList 并将这个修改后的 ArrayList 放在我的线程之外。

这是我的代码,它可以工作,但是当我从外部读取我的 ArrayList 时,它具有正确的大小,但是此 ArrayList 中的所有元素都是最后添加的元素,我的意思是如果最后一个元素具有 pollingCode,pollingType,polling Value = 0, all elements在数组中具有相同的值。

有人知道为什么会这样吗?

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();    
   }

}

4

4 回答 4

2

您是否尝试过在循环中创建一个新的 InputEvent。您只有一个,即添加列表,然后更新其中的值InputEvent

InputEvent ie= new InputEvent();
while (m_bMonitorOn) {
    ie= new InputEvent();
 ...
于 2013-03-18T15:12:46.387 回答
2

仅供参考,这与多线程无关。

您正在重新使用相同的 InputEvent 对象。因此,您调用setCode的是同一 InputEvent 的 setCode 方法。添加只是每次都会添加相同的IE实例。

例如,尝试(假设列表大小 > 1)

if(eventList.get(0) == eventList.get(1)){
   //re using the same object
}

您应该在 for 循环内移动 InputEvent 的创建分配。

于 2013-03-18T15:14:35.617 回答
2

无需详细研究您的代码:您的列表不是线程安全的。我建议您使用ArrayBlockingQueue之类的东西在线程之间共享事件。这将消除重大问题,无论如何都是正确的做法。

于 2013-03-18T15:15:04.713 回答
0

你有两个错误:

首先,改变:

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);
        }
    }
}
于 2013-03-18T15:29:01.373 回答