缘由

最近在做 android 性能数据抓取的功能,原来写的通过在手机端建立 socketserver 的方法在部分手机上失效,所以又改用 adb 命令来抓取性能数据

性能数据

问题

写好了各个数据获取的静态方法,例如获取电池电量百分比的,最后再逐一调用每个方法即可,这都没有问题,
问题是结果从获取性能数据到全部结果拿到以后,共花了约 17、18 秒,时间太长了

public static String batteryRate(String serialNum){
    String battCmd = System.getProperty("adb") + " -s " + serialNum + " shell dumpsys battery";
    Common com = new Common() {
        @Override
        protected String filterResult(BufferedReader br) {
            String result = "";
            String line;
            try {
                while ((line = br.readLine()) != null) {
                    if (line.trim().contains("level")) {
                        result = line.split(":")[1].trim();
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return result;
        }

    };
    return com.runCMD(battCmd);
}

优化思路

因为各个命令并没有相互的依赖关系,所以如果能一起执行就好了

优化方法

通过创建一个任务列表 ArrayList>,将需要执行的命令都放到这个列表中,然后一次一起执行,
即原来的串行调用,改成了并行调用,共花了约 2、3 秒

public static ExecutorService getMyThreadPools() {
    if (myThreadPools == null) {
        myThreadPools = Executors.newFixedThreadPool(16);
    }
    return myThreadPools;
}
ArrayList<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
    @Override
    public String call() throws Exception {
        return BattUtils.batteryRate(serialNum);
    }
});
List<Future<String>> result = new ArrayList<Future<String>>();
Map<String,String> map = new HashMap<String,String>();
try {
    result = IExecuter.getMyThreadPools().invokeAll(tasks, 8000, TimeUnit.MILLISECONDS);
    /**获取电池当前剩余电量*/
    map.put(BATTERY_RATE, result.get(0).get());
} catch (Exception e) {
    e.printStackTrace();
}       

小感慨

又 get 了一个新技能,捡起一粒小芝麻,OH YEAH,欢迎交流学习


↙↙↙阅读原文可查看相关链接,并与作者交流