Android 域名测速工具类

直接上代码

public class ListDomainSort {
    //域名测速
    public static final int DOMAIN_TYPE = 0x1009;
    //ip ping
    public static final int PING_TYPE = 0x1010;
    //rtmp测速
    public static final int RTMP_TYPE = 0x1011;

    public int threadNum = 0;//执行任务的子线程数量
    public int workNum = 0;//任务数量
    private ExecutorService service; //线程池
    private ArrayBlockingQueue<String> blockingQueue; //结果列表
    private CountDownLatch latch; //任务锁
    private int acceptCount; //返回数量
    private boolean ignoreError = true; //忽略失败
    private int TYPE = DOMAIN_TYPE; //测速类型
    private static ListDomainSort listHostSort;


    private List<String> oldList = new ArrayList<>();//原数据

    private CallHostsDomain callHosts; //接口回调

    private ListDomainSort() {
    }

    public static ListDomainSort getSortUtil() {
//        if (listHostSort == null) {
//            listHostSort = new ListDomainSort();
//        }
        return new ListDomainSort();
    }

    /**
     * 执行测速
     *
     * @param oldList     需要测速的列表
     * @param acceptCount 按速度排序之后需要的前几位数据
     * @param ignoreError 是否忽略失败的 默认是ture
     * @param callHosts   回调接口
     */
    public void startSort(List<String> oldList, int acceptCount, boolean ignoreError, int type, final CallHostsDomain callHosts) {
        this.callHosts = callHosts;
        this.TYPE = type;
        this.acceptCount = acceptCount;
        this.oldList = oldList;
        this.ignoreError = ignoreError;
        //1.創建和列表数量相同的线程
        setUp();
        //2.抽取做工单元
        for (int i = 0; i < workNum; i++) {
            service.execute(new WorkRunnable(oldList.get(i)));
        }
        //3.等待所有工作线程执行完成
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    latch.await();//等待子线程的所有任务完成
                    //停止所有线程
                    service.shutdownNow();
                    callHosts.callHostList(copyIterator(blockingQueue.iterator()));
                } catch (Exception e) {
                    callHosts.callHostList(copyIterator(blockingQueue.iterator()));
                }
            }
        }).start();
    }

    //单个线程逻辑
    class WorkRunnable implements Runnable {
        private String host;

        public WorkRunnable(String ip) {
            host = ip;
        }

        @Override
        public void run() {
            //4.对每个线程执行回来的结果进行依次加入列表
            try {
                if (ignoreError) {
                    countExeuct(host);
                    blockingQueue.put(host);
                    //完成一个任务就调用一次
                    latch.countDown();
                } else {
                    if (countExeuct(host)) {
                        blockingQueue.put(host);
                        //完成一个任务就调用一次
                        latch.countDown();
                    }
                    if (workNum == acceptCount) {
                        //完成一个任务就调用一次
                        latch.countDown();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行测速单元
     *
     * @param host 需要测速的域名或IP
     * @return
     */
    private boolean countExeuct(String host) {

        if (TYPE == DOMAIN_TYPE) {
            return testDomain(host);
        } else if (TYPE == PING_TYPE) {
            return testPing(host);
        } else if (TYPE == RTMP_TYPE) {
            return testRtmp(host);
        } else {
            return false;
        }
    }

    private boolean testRtmp(String host) {
        return RtmpClient.open(host, false) > 0;
    }

    private boolean testPing(String host) {
        Runtime runtime = Runtime.getRuntime();
        try {
            if (host.equals("0")) {
                return false;
            }
            //ping 1次 超时3秒 数据包512 TTL 255
            String prog = "/system/bin/ping -w 1 -c 1 -i 1 -s 128 -t 255 " + host;
            Process mIpAddrProcess = runtime.exec(prog);
            int mExitValue = mIpAddrProcess.waitFor();
            return mExitValue == 1;
        } catch (Exception ignore) {
        }
        return false;
    }

    private boolean testDomain(String host) {
        String result = httpGet(host);
        if (result != null) {
            try {
                JSONObject object = new JSONObject(result);
                int code = object.optInt("code");
                L.d("OTHER", "测速" + host + "==>>" + (code == 123));
                return code == 123;
            } catch (JSONException e) {
                e.printStackTrace();
                L.d("OTHER", "测速" + host + "==>>" + false);
            }
        }
        return false;
    }


    private void setUp() {
        this.workNum = oldList.size();
        this.threadNum = oldList.size();
        //创建线程池
        service = Executors.newFixedThreadPool(threadNum);
        //计数器的值为任务的数量
        latch = new CountDownLatch(acceptCount);
        blockingQueue = new ArrayBlockingQueue<>(acceptCount);
    }

    public interface CallHostsDomain {
        void callHostList(List<String> newList);
    }

    private <T> List<T> copyIterator(Iterator<T> iter) {
        List<T> copy = new ArrayList<T>();
        while (iter.hasNext())
            copy.add(iter.next());
        return copy;
    }


    /**
     * get的方式请求
     */
    private String httpGet(String host) {
        //get的方式提交就是url拼接的方式
        try {
            URL url = new URL(host + "/ping.php");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(5000);
            connection.setRequestMethod("GET");
            //获得结果码
            int responseCode = connection.getResponseCode();
            if (responseCode == 200) {
                //请求成功 获得返回的流
                InputStream is = connection.getInputStream();
                return IOUtils.toString(is);
            } else {
                //请求失败
                return null;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

使用方式

        ArrayList<String> list = new ArrayList<>();
        list.add("http://www.xxx.com");
        list.add("http://www.xxx.com");
            ListDomainSort.getSortUtil().startSort(list, 5, false, ListDomainSort.DOMAIN_TYPE, new ListDomainSort.CallHostsDomain() {
                @Override
                public void callHostList(List<String> newList) {
                    L.d("OTHER", "测速结果==>>" + JSON.toJSONString(newList).toString());
                }
            });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342