很多线程是一个处理程序和很少的经验

时间:2012-09-17 21:53:48

标签: android multithreading synchronization handler

我试图列出连接到wifi的本地机器。执行此操作的简单方法是将每个IP从a.b.c.1 ping到a.b.c.255,但我们都知道这将“永远”。

因此我想使用Threads!

我所拥有的是包含以下内容的 MainActivity

list = (ListView) findViewById(R.id.list);
ipList.add("Nothing yet");

adapter = new ArrayAdapter<String>(this, R.layout.simplerow, ipList);
list.setAdapter(adapter);

networkList = new NetworkList(); //This is the shared list between the Threads

for(int i = 1; i<255; i++){  //Tries to ping the range of IP's

    Ping ping = new Ping(localIP + i, networkList)
    new Thread(ping).start();
}

班级 Ping 实现了Runnable:

public void run() {
  try {
    InetAddress address = InetAddress.getByName(IP);

    if(address.isReachable(2000)){
        synchronized(networkList){
            networkList.addIP(address.getHostAddress());
            MainActivity.handler.sendEmptyMessage(0); //probably wrong
        }
    }
  } catch (Exception e) {}
}

我不确定同步的使用是否正确,但请坚持下去!类 NetworkList 是同步事物发生的地方:

public synchronized void addIP( String IP ){
    foundIPs.add(IP);
}

public synchronized ArrayList<String> getIPList(){
    return foundIPs;
}

行。返回 MainActivity

这可能是非常错误的,但它是我设法做的:

    handler = new Handler() {
        public void sendEmptyMessage(android.os.Message msg) {
            adapter.clear();
            synchronized(networkList){
                ipList = networkList.getIPList();
            }
            adapter.notifyDataSetChanged();
        }
    };

这里有什么问题?我希望在线程获得ping响应时立即更新列表。换句话说,我希望看到ListView在找到新IP时展开,而不仅仅是在ping过程完成后检索完整列表。

2 个答案:

答案 0 :(得分:1)

我认为问题在于适配器本身没有获得对新的IP地址列表的引用,因此它可能会查看最旧的没有条目的列表。

我可以通过查看代码来看到它:

adapter = new ArrayAdapter<String>(this, R.layout.simplerow, ipList);
...
ipList = networkList.getIPList();

答案 1 :(得分:1)

使用ipList = networkList.getIPList();您正在创建一个新列表,该列表是阵列适配器不知道的。您应该直接在适配器上进行调用,例如ArrayAdapter.add或ArrayAdapter.addAll()。