在Android Studio中运行ExecutorService时出现类异常错误

问题描述 投票:0回答:1

我有一个使用AsyncTask运行扫描的活动。在AsyncTask的doInbackground方法中,我调用了一个实现Callable的runnable类(我需要从类中返回一些东西),这个类与其他主机建立套接字连接,如果连接成功,那么它会尝试解析规范名称。这个主机名是我想从线程池中获得的。我遇到的问题是当我试图从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)

asynctask类

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
1个回答
0
投票

List<Node> call()返回列表。当你将可调用提交给执行者时,它会变成Future<List<Node>>而你的列表需要Future<Node>

Java不会在运行时验证泛型参数,因此在添加Future<List<Node>>而不是Future<Node>时没有错误。但是,当你从列表中获取并转换为Node时,它就会失败。

© www.soinside.com 2019 - 2024. All rights reserved.