简体   繁体   English

日期选择器的Android IllegalArgumentException

[英]Android IllegalArgumentException for Date picker

The date picker I used for my activity crashed on KitKat but works on every other newer operating systems. 我用于活动的日期选择器在KitKat上崩溃了,但在其他所有较新的操作系统上都可以使用。 This is the exception I get on old devices: 这是我在旧设备上遇到的异常:

java.lang.IllegalArgumentException: fromDate: Mon Apr 10 07:59:25 EDT 2017 does not precede toDate: Mon Apr 10 07:59:25 EDT 2017 java.lang.IllegalArgumentException:fromDate:Mon Apr 10 07:59:25 EDT 2017不早于Date:Mon Apr 10 07:59:25 EDT 2017

Code block stack trace is pointing at: 代码块堆栈跟踪指向:

private void showDatePicker(){
   DatePickerDialog datePickerDialog = new DatePickerDialog(
   getActivity(), this, calendar.get(Calendar.YEAR),  calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
   //this is where the crash happens
   datePickerDialog.getDatePicker().setMinDate(new Date().getTime());
   datePickerDialog.show();
}

Please let me know if the information regarding the question is sufficient. 请让我知道有关该问题的信息是否足够。 Any fix for this? 有什么解决办法吗?

I fix this issue applying a delay: 我会延迟解决此问题:

private void showDatePicker(){
   DatePickerDialog datePickerDialog = new DatePickerDialog(
   getActivity(), this, calendar.get(Calendar.YEAR),  calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
   //this is where the crash happens
   datePickerDialog.getDatePicker().setMinDate(new Date().getTime() - 10000);
   datePickerDialog.show();

} }

To solve this issue create a timestamp for minDate just before instantiation of DatePickerDialog: 要解决此问题,请在实例化DatePickerDialog之前为minDate创建一个时间戳:

private void showDatePicker(){
   long now = System.currentTimeMillis();
   DatePickerDialog datePickerDialog = new DatePickerDialog(
      getActivity(), this, calendar.get(Calendar.YEAR),  calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
   datePickerDialog.getDatePicker().setMinDate(now);
   datePickerDialog.show();
}

This crash happens due to a bug in CalendarView for pre-API21, and for calendarViewMode == MODE_HOLO for API21. 由于API21之前版本的CalendarView和API21的calendarViewMode == MODE_HOLO的错误,导致发生此崩溃。

Although setMinDate contains a correction highlighted with a comment: 尽管setMinDate包含以注释突出显示的更正:

public void setMinDate(long minDate) {
    ...
    mMinDate.setTimeInMillis(minDate);
    // make sure the current date is not earlier than
    // the new min date since the latter is used for
    // calculating the indices in the adapter thus
    // avoiding out of bounds error
    Calendar date = mAdapter.mSelectedDate;
    if (date.before(mMinDate)) {
        mAdapter.setSelectedDay(mMinDate);
    }
    // reinitialize the adapter since its range depends on min date
    mAdapter.init();

The check in setSelectedDay compares mMinDate and mSelectedDate only with date accuracy: setSelectedDay的检查仅将mMinDatemSelectedDate进行日期精度比较:

public void setSelectedDay(Calendar selectedDay) {
    if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
            && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
        return;
    }

mSelectedDate and mMinDate are points into the same day, so that mSelectedDate will remain unchanged (ie in a wrong state mSelectedDate < mMinDate ). mSelectedDatemMinDate是同一天的点,因此mSelectedDate将保持不变(即,处于错误的状态mSelectedDate < mMinDate )。

Then the control flow will run up to mAdapter.init , and then into getWeeksSinceMinDate . 然后,控制流将运行到mAdapter.init ,然后运行到getWeeksSinceMinDate In this function a comparison of mMinDate and mSelectedDate will be performed with millisecond accuracy: 在此函数中,将以毫秒精度对mMinDatemSelectedDate进行比较:

private int getWeeksSinceMinDate(Calendar date) {
    if (date.before(mMinDate)) {
        throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
                + " does not precede toDate: " + date.getTime());
    }

And because mSelectedDate was initialized in few milliseconds before mMinDate the crash will occur. 并且由于mSelectedDatemMinDate之前的几毫秒内初始化,因此崩溃将发生。

In a newer implementation this code was rewritten, so this issue is missing for API21+. 在较新的实现中,此代码被重写,因此API21 +缺少此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM