当使用Calendar.SATURDAY作为星期的最后一天时,Holo日历崩溃

问题描述:

我正在使用Holo Calendar library当使用Calendar.SATURDAY作为星期的最后一天时,Holo日历崩溃

这是一个大量的代码,所以我不能把它包含在这个线程中。希望有人会看到使用过它的人,但图书馆是免费的,页面底部有一个链接到您可以打开的已完成项目。

您可以设置日历的开始和结束日期的方式如下:

mMultiCalendarView.setFirstDayOfWeek(Calendar.MONDAY); 
mMultiCalendarView.setLastDayOfWeek(Calendar.SUNDAY); 

但是,这是一个古怪的日历给我。一周的第一天是星期一,然后两周末都是星期一结束。我希望每周都有星期六到星期六。

我可以在一周的第一天设置为任何东西,没有问题,但是下面一行:

mMultiCalendarView.setLastDayOfWeek(Calendar.SATURDAY); 

导致应用程序停顿了,不管是一周的第一天。这似乎是在无限循环,日志猫不断吐出类似以下内容:

02-10 20:29:03.876 2143-2143/(appName) I/dalvikvm-heap﹕ Clamp target GC heap from 96.710MB to 96.000MB 
02-10 20:29:03.876 2143-2143/(appName) D/dalvikvm﹕ GC_FOR_ALLOC freed 1272K, 8% free 90712K/98260K, paused 45ms, total 45ms 

,直到有以下内存警告应用程序崩溃:

FATAL EXCEPTION: main 
java.lang.OutOfMemoryError 

的错误指向库中的下列行:

at com.vdesmet.lib.calendar.CalendarView.createHeaders(CalendarView.java:286) 
at com.vdesmet.lib.calendar.CalendarView.initView(CalendarView.java:93) 
at com.vdesmet.lib.calendar.AbstractCalendarView.onLayout(AbstractCalendarView.java:397) 

其是下面的行分别为:

LINE 286: headers.addView(header); 
LINE 93: createHeaders(); 
LINE 397: initView(); 

我很抱歉,这一切都意味着很少没有手头的库。我已经梳理了每一行代码,每个循环都处理一周中的几天,但我无法弄清楚这一点。

有没有人与此工作,或没有人有任何想法导致崩溃(基于在this Github page库可用)?

从源代码寻找,误差似乎是由不可达结束条件为do-while循环造成的,特别是在line 288-291内部createHeaders()

private void createHeaders() { 

    ... 

    final int firstDayOfWeek = mFirstDayOfWeek; 
    final int lastDayOfWeek = mLastDayOfWeek; 

    ... 

    int dayOfWeek = firstDayOfWeek; 

    do { 

     ... 

     // increment dayOfWeek, make sure it's a valid day 
     dayOfWeek = dayOfWeek % 7; 
     dayOfWeek++; 
    } while(dayOfWeek != lastDayOfWeek + 1); 

    ... 

} 

Calendar.SATURDAY的值是7,而不是6作为显影剂什么预期。 (确切地说,它从Calendar.SUNDAY(1),Calendar.MONDAY(2),...到Calendar.SATURDAY(7))开始。

另一方面,dayOfWeek % 7将只返回0-6,然后加1,你会得到1-7。但是循环的最终条件是dayOfWeek == lastDayOfWeek + 1。当它是Calendar.SATURDAY时,它是(7 + 1) == 8,这是超出范围。因此,循环不会结束,导致OutOfMemoryError

解决方法是将结束条件更改为while(dayOfWeek != (lastDayOfWeek % 7 + 1));以确保lastDayOfWeek也从1-7进行换行。

补遗

的变化需要对2条线被施加内部CalendarView.java

  • createHeaders()line 291

    } while(dayOfWeek != (lastDayOfWeek % 7 + 1)); 
    
  • initView()line 119

    while((currentDay.get(Calendar.MONTH) + 1) % MONTHS_IN_YEAR == currentMonth || 
         currentDay.get(Calendar.MONTH) == currentMonth || 
         currentDay.get(Calendar.DAY_OF_WEEK) != (lastDayOfWeek % 7 + 1)) { 
    

感谢pandes for follow-up on their GitHub's issue

+0

感谢您的回答!我前一阵子想到了,但忘记了我发布了这个问题。是的,这与条件中的mod运算符有关。没有测试过这个,但会选择答案,直到证明错误(但它听起来都是正确的!)。 – Birrel 2015-06-09 03:50:02