有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用于日期选择器的java Android IllegalArgumentException

我用于活动的日期选择器在KitKat上崩溃,但在其他所有更新的操作系统上都能工作。这是我在旧设备上遇到的例外:

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

代码块堆栈跟踪指向:

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();
}

请让我知道关于这个问题的信息是否足够。有办法吗


共 (2) 个答案

  1. # 1 楼答案

    要解决此问题,请在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();
    }
    

    此崩溃是由于API21之前版本的CalendarView和API21的calendarViewMode == MODE_HOLO中的错误造成的

    尽管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();
    

    签入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;
        }
    

    mSelectedDatemMinDate是指向同一天的点,因此mSelectedDate将保持不变(即处于错误状态mSelectedDate < mMinDate

    然后控制流将运行到mAdapter.init,然后进入getWeeksSinceMinDate。在该函数中,mMinDatemSelectedDate的比较将以毫秒的精度进行:

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

    由于mSelectedDatemMinDate之前的几毫秒内初始化,崩溃将发生

    在一个较新的实现中,这段代码被重写,因此API21+缺少这个问题

  2. # 2 楼答案

    我通过延迟解决了这个问题:

    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();
    

    }