关闭

Android异常--无序HashMap导致Android5.0及5.0以后的手机连接服务器异常

标签: hashmap无序列表javaandroid版本兼容
481人阅读 评论(0) 收藏 举报
分类:

前言

手上的一个项目,在我测试用的手机上都正常,今天在同事手机上登录失败.测试机系统版本是Android4.4,出现问题的手机系统版本是Android5.0,测试排查之后发现Android系统版本上面map内顺序排列不同的原因导致.

错误原因分析

 项目是采用socket通信,访问接口时需要给服务器发送一些信息,这些信息在写入流之前是以字符串的格式存在的

这个数据字符串里面有一个字段拼接,这个顺序需要严格和服务器保持一致,

逻辑是:

1.按照规定的顺序放到一个map里面,然后循环取出拼接,

2.循环取出拼接(因为是列表是封装的公共方法,需要对应不同的接口参数,所以用的是反射得到取出)


然而这是错的,错的!!!!原因在于:HashMap是无序排列的!尽管看着数据是顺序添加排列进去的,所以不能保证取出数据的顺序.


这是取数据的代码:

  ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        //java的反射
        // Class userCla = (Class) bean.getClass();
        StringBuilder myBuilder = new StringBuilder();
        Class userCla = (Class) model_in.getClass();
        Field[] fs = userCla.getFields();


        for (int i = 0; i < fs.length; i++) {
            try {
                Field f = fs[i];
                f.setAccessible(true);
                Object val = f.get(model_in);
                String name = f.getName();



                //将所有键的名值对放入map中
                if (name.compareTo("Sys_Key") != 0) {

                    try {
                        map.put(f.getName(), val.toString());
                    }catch (Exception ex){

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

问题解决方法:

在拼接前使用某些方法将map排序一下


我使用的方法是:新建一个TreeMap,制定按照字母升序的规则,将所有数据重新排序(注意: 使用这样的规则,也是因为服务端那边取数据也是这样的规则,如果你遇到了这种情况,请结合自己项目服务端的情况做排序处理)

这里贴一下我排序采用的方法:

	/**
	 * 对Map按Key升序排序
	 * 
	 * @param oriMap 要排序的map
	 * @return 
	 */
	public static Map<String, String> sortMapByKey(Map<String, String> oriMap) {
		if (oriMap == null || oriMap.isEmpty()) {
			return null;
		}
		Map<String, String> sortedMap = new TreeMap<String, String>(
				new Comparator<String>() {
					@Override
					public int compare(String lhs, String rhs) {
						return lhs.compareToIgnoreCase(rhs);
					}
				});
		sortedMap.putAll(oriMap);
		return sortedMap;
	}


问题思考:

为什么在测试机4.4上一直都正常,同事的5.0就不行了?

HashMap虽说是无序,但是肯定是有一定顺序的,否则不会再测试机上每次都能保持一样的顺序取出,登录成功了,虽然不知道是什么,顺序规则,但是很显然,而且这个顺序和系统版本有关,不同android版本的map列表有可能不同.


最后:

说到这,其实发现问题解决的思路和刚开始的想法完全不同,原因在于,代码之前写的真是太不严谨了,对Java几种表的了解不够,基础知识不足,对服务端那边的情况不清楚,不然早严格排序就好了,还哪来这么多幺蛾子,作为一个教训,谨记之~


附上一篇关于Java Map,List ,Set 有序无序的博客http://www.cnblogs.com/grasshopper/p/4168972.html


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:166958次
    • 积分:2634
    • 等级:
    • 排名:第15593名
    • 原创:86篇
    • 转载:4篇
    • 译文:0篇
    • 评论:91条
    如果你想了解更多的我
    博客专栏
    最新评论