Android: StackOverflowError в DatePicker - PullRequest
       0

Android: StackOverflowError в DatePicker

0 голосов
/ 31 октября 2011

Я присоединяюсь к Timepicker и Datepicker. За исключением того, что я должен добавить лимит к дате. К сожалению, я получил ошибку, с которой я не могу справиться. Может быть, кто-то может помочь ... Произошла ошибка в datePicker.updateDate (oldy, oldm, oldd);

Код из моего диалога DateTimePicker:

        datePicker = (DatePicker) findViewById(R.id.datePickerDate);
    timePicker = (TimePicker) findViewById(R.id.timePickerTime);

    datePicker.init(DAFAULT_START_YEAR, DEFAULT_START_MONTH, DEFAULT_START_DAY,
        new OnDateChangedListener() {
        @Override
        public void onDateChanged(final DatePicker view, final int year, final int monthOfYear,
                        final int dayOfMonth) {
                    Date currChoice = new Date(year, monthOfYear, dayOfMonth);
                    if (currChoice.before(currentDateTime) || currChoice.equals(currentDateTime)) {
                        //do some things
                    } else {
                        datePicker.updateDate(oldy, oldm, oldd);
                    }
                }
            });
    datePicker.updateDate(y, m, d);

Ошибка:

Thread [<1> main] (Suspended (exception StackOverflowError))    
DataSetObservable.notifyChanged() line: 37  
CalendarView$WeeksAdapter(BaseAdapter).notifyDataSetChanged() line: 50  
CalendarView$WeeksAdapter.setSelectedDay(Calendar) line: 1005   
CalendarView.goTo(Calendar, boolean, boolean, boolean) line: 750    
CalendarView.setDate(long, boolean, boolean) line: 623  
DatePicker.updateCalendarView() line: 636   
DatePicker.updateDate(int, int, int) line: 496  
DateTimeDialog.init() line: 151 
DateTimeDialog.<init>(Context, String) line: 88 
MyActivity$3.onClick(View) line: 395    
EditText(View).performClick() line: 3117    
View$PerformClick.run() line: 11941 
ViewRoot(Handler).handleCallback(Message) line: 587 
ViewRoot(Handler).dispatchMessage(Message) line: 92 
Looper.loop() line: 132 
ActivityThread.main(String[]) line: 4123    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 491  
ZygoteInit$MethodAndArgsCaller.run() line: 841  
ZygoteInit.main(String[]) line: 599 
NativeStart.main(String[]) line: not available [native method]  

Logcat:

10-31 14:53:49.390: E/AndroidRuntime(5348): FATAL EXCEPTION: main
10-31 14:53:49.390: E/AndroidRuntime(5348): java.lang.StackOverflowError
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.view.View.invalidate(View.java:7178)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.view.View.invalidate(View.java:7159)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView.invalidateCursor(TextView.java:3826)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView.spanChange(TextView.java:6933)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:7059)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:918)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:615)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:518)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.Selection.setSelection(Selection.java:74)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.Selection.setSelection(Selection.java:85)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:288)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView.setText(TextView.java:2814)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView.setText(TextView.java:2691)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.EditText.setText(EditText.java:78)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.TextView.setText(TextView.java:2666)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.NumberPicker.updateInputTextView(NumberPicker.java:1427)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.NumberPicker.setDisplayedValues(NumberPicker.java:1041)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.updateSpinners(DatePicker.java:593)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.updateDate(DatePicker.java:495)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at myapp.dialog.DateTimeDialog$3.onDateChanged(DateTimeDialog.java:146)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.notifyDateChanged(DatePicker.java:666)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.updateDate(DatePicker.java:497)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at myapp.dialog.DateTimeDialog$3.onDateChanged(DateTimeDialog.java:146)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.notifyDateChanged(DatePicker.java:666)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.updateDate(DatePicker.java:497)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at myapp.dialog.DateTimeDialog$3.onDateChanged(DateTimeDialog.java:146)
10-31 14:53:49.390: E/AndroidRuntime(5348):     at android.widget.DatePicker.notifyDateChanged(DatePicker.java:666)
etc

Ответы [ 2 ]

2 голосов
/ 31 октября 2011

Вы звоните updateDate из onDateChanged, вызывая бесконечную рекурсию. Похоже, вы пытаетесь отфильтровать прошлые даты. Возможно, вместо этого попробуйте DatePicker.setMinDate .

Обновление

Чтобы быть немного более точным, ваша методология не слишком ошибочна. Программистам часто приходится устанавливать значения от самих слушателей. Проблема в том, что вы ничего не делаете, чтобы убить рекурсию. Посмотрите на ваш код ниже:

Date currChoice = new Date(year, monthOfYear, dayOfMonth);
if (currChoice.before(currentDateTime) || currChoice.equals(currentDateTime)) {
    //do some things
} else {
    datePicker.updateDate(oldy, oldm, oldd);
}

Если текущая выбранная дата меньше или равна текущей дате, вы устанавливаете значение обратно на предыдущее значение, но вы не проверяете, является ли это предыдущее значение также меньше или равно текущей дате. Это означает, что если старая дата меньше текущей, которую вы собираетесь использовать вечно. Вторая проверка исправит это:

Date currChoice = new Date(year, monthOfYear, dayOfMonth);
Date oldChoice = new Date(oldy, oldm, oldd);
if (currChoice.before(currentDateTime) || currChoice.equals(currentDateTime)) {
    //do some things
} else if (oldChoice.before(currentDateTime) || oldChoice.equals(currentDateTime)) {
    // Maybe do nothing, maybe set the date to tomorrow.  Your call.
} else {
    datePicker.updateDate(oldy, oldm, oldd);
}

Конечно, я все еще думаю, что setMinDate - ваш лучший выбор, но это именно то, что происходит на самом деле.

2 голосов
/ 31 октября 2011

Ваш звонок на updateDate() изнутри onDateChanged() вызывает одно и то же событие, снова, снова и снова.Это происходит до тех пор, пока у вас не закончится место в стеке.

Используйте логическую переменную или что-то в вашей реализации onDateChanged (), чтобы избежать рекурсивного запуска события.

...