【发布时间】:2019-09-11 02:32:42
【问题描述】:
我有一个使用 AsyncTask 运行扫描的活动。在 AsyncTask 的 doInbackground 方法中,我调用了一个实现 Callable 的可运行类(我需要从该类返回一些内容),该类与其他主机建立套接字连接,如果连接成功,则它会尝试解析规范名称。这个主机名是我想从线程池中得到的。我遇到的问题是当我试图从 resultList 中获取回报时。
public List<Future<Node>> resultList = new ArrayList<>();
public Future<Node> result = null;
这是我得到的例外。显然,当使用 for 循环遍历 resultList 以获取结果时。有一个演员表异常,因为我试图收集错误的数据。
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.pctechtips.netdroid.Node
at org.pctechtips.netdroid.activity.IpScanActivity$TaskScanNetwork.doInBackground(IpScanActivity.java:202)
at org.pctechtips.netdroid.activity.IpScanActivity$TaskScanNetwork.doInBackground(IpScanActivity.java:156)
异步任务类
private class TaskScanNetwork extends AsyncTask<Void, Void, Void> {
static final int NUMTHREADS = 254;
String hostname;
String subnet = ip.substring(0, ip.lastIndexOf("."));
int startIp = 1;
int range = (numOfHost / NUMTHREADS); //range to be scanned by every thread
int stopIp = startIp + range;
List<Future<Node>> resultList = new ArrayList<>();
Future<Node> result = null;
ExecutorService executor = Executors.newFixedThreadPool(NUMTHREADS);
static final int TIME_OUT = 1000;
@Override
protected void onPreExecute() {
hostList.clear();
Node node = new Node(ip, mac);
hostList.add(node);
scanProgress.setMax(numOfHost);
scanProgress.setProgress((numOfHost * 10) / 100 ); //set progress bar at 10%
// statusMsg.setText("Scanning " + subnet + ".0/" + cidr);
}
/* initialaze threads */
@Override
protected Void doInBackground(Void... params) {
Log.v("BACKGROUND", "doInBackground stuff");
for(int i = 0; i < NUMTHREADS; i++) {
IpScanRunnable ipScan = new IpScanRunnable(subnet, startIp, stopIp);
result = executor.submit(ipScan);
resultList.add(result);
startIp = stopIp;
stopIp = startIp + range;
}
try {
new Thread().sleep(TIME_OUT);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
android.os.Debug.waitForDebugger();
for(Future<Node> future : resultList) {
try {
Log.v("NODE", future.get().getHostName());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
publishProgress();
return null;
}
@Override
protected void onProgressUpdate(Void... params) {
networkAdapter.notifyDataSetInvalidated();
}
@Override
protected void onPostExecute(Void aVoid) {
networkTxtView.setText(subnet + ".0/ " + cidr);
numOfHostTxtView.setText(hosts+"");
scanProgress.setProgress(254);
}
}
可运行类
package org.pctechtips.netdroid.runnable;
import org.pctechtips.netdroid.Node;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
public class IpScanRunnable implements Callable {
private List<Node> results;
private static final String TAG = "IPSCANRUNNABLE";
private final static int TIMEOUT = 1000;
private final static int PORT = 7;
private String subnet;
private Integer startIp;
private Integer stopIp;
public IpScanRunnable(String subnet, int start, int stop) {
this.subnet = subnet;
this.startIp = start;
this.stopIp = stop;
results = new ArrayList();
}
@Override
public List<Node> call() throws Exception {
Socket socket = null;
for(int i = startIp; i < stopIp; i++) {
String ip = subnet + "." + i;
socket = new Socket();
try {
// android.os.Debug.waitForDebugger();
InetAddress ipAdd = InetAddress.getByName(ip);
byte[] ipBytes = ipAdd.getAddress();
socket.setTcpNoDelay(true);
socket.connect(new InetSocketAddress(InetAddress.getByAddress(ipBytes), PORT), TIMEOUT);
String hostname = ipAdd.getCanonicalHostName();
Node node = new Node(ip);
node.setHostName(hostname);
results.add(node);
}
catch (Exception ex){
}
}
return results;
}
public List<Node> getResults() {
return results;
}
}
【问题讨论】:
标签: java android multithreading exception callable