文章目录

在研究从阿里云下载文件的时候(由于阿里SDK不支持android,所以用的是第三方SDK),总是出现dialog导致内存泄露的错误。找了许久的bug,最后发现,真正的原因是在Activity中出现异常导致生成dailog的Activity对象提前死亡,这时候dailog并没有dismiss。

进一步研究发现真正的引起Activity死亡的错误是Ossclient客户端引起的unparseable date错误,最终的错误根源在jar包中,于是找来源码,将错误定位在下面的函数:

1
2
3
4
public static Date getDateFromString(String format, String dateString)
throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(dateString);

在执行字符串转换到date对象时,出现错误。查找到调用getDateFromString方法的函数

1
2
3
public static Date getGMTDateFromString(String dateStr) throws ParseException {
return getDateFromString("E, dd MMM yyyy HH:mm:ss 'GMT'", dateStr);
}

发现传入的形参format是E, dd MMM yyyy HH:mm:ss ‘GMT’这个格式在中文环境下并不支持,把手机的语言调成英文,错误就消失了。但是要在中文环境下运行不报错的方法就是在新建SimpleDateFormat类时,用第二个参数规定所在的地点在非中国地区。

1
2
3
4
5
public static Date getDateFromString(String format, String dateString)
throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat(format,Locale.ENGLISH );
return sdf.parse(dateString);
}

下面进一步研究SimpleDateFormat这个类的问题,通过查阅OSChina的android API(谷歌被墙你懂的)提供的在线文档可以看到SimpleDateFormat的构造方法有四个:
image
其中

1
2
3
4
public SimpleDateFormat(String pattern,Locale locale)
Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the given locale. Note: This constructor may not support all locales. For full coverage, use the factory methods in the DateFormat class.
Parameters:pattern - the pattern describing the date and time formatlocale - the locale whose date format symbols should be used
Throws:NullPointerException - if the given pattern or locale is nullIllegalArgumentException - if the given pattern is invalid

而public SimpleDateFormat(String pattern)使用传入的格式和系统所在地区默认的日期格式标志

1
2
3
4
public SimpleDateFormat(String pattern)
Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the default locale. Note: This constructor may not support all locales. For full coverage, use the factory methods in the DateFormat class.
Parameters:pattern - the pattern describing the date and time format
Throws:NullPointerException - if the given pattern is nullIllegalArgumentException - if the given pattern is invalid

由于很多日期格式在中文语境下是不能转换成date对象,所以推荐使用指定local的构造函数

题外话SimpleDateFormat不是线程安全的,可以看这篇精彩的文章
这也同时提醒我们在开发和设计系统的时候注意下一下三点:
  1.自己写公用类的时候,要对多线程调用情况下的后果在注释里进行明确说明
  2.多线程环境下,对每一个共享的可变变量都要注意其线程安全性
  3.我们的类和方法在做设计的时候,要尽量设计成无状态的

文章目录