Недавно я перевел большую часть своего проекта на котлин. Теперь я сталкиваюсь с несколькими необычными ошибками, которые, похоже, связаны с библиотеками аннотаций. Излишне говорить, что на Java этого не произошло.

Я опишу случаи - один в Dagger и один в Butterknife.

1. При наличии двух методов @Provides в разных моделях с одинаковыми именами. Например, в файле "FooProvider.kt" есть метод provideFooOrBar.

@Module
class FooProvider(private val view: FooActivity) {
    ... 
    @Provides @FooScope fun provideView() = view
    @Provides @FooScope fun provideFooOrBar() = Foo()
}

И если есть еще один файл BarProvider.kt с тем же именем метода

@Module
class BarProvider(private val view: BarActivity) {
    ...
    @Provides @BarScope fun provideView() = view
    @Provides @BarScope fun provideFooOrBar() = Bar()
}

В этом случае Dagger не может создать некоторые фабричные библиотеки, и я получаю следующую ошибку компиляции: Error:(27, 32) error: cannot find symbol class FooProvider_ProvideFooOrBarFactory

Образец проекта, в котором воспроизводится проблема, можно найти по адресу https://github.com/maxandron/DaggerIssue325.

2. Это проблема при использовании Butterknife. При наличии двух аннотированных переменных @Bind в двух разных классах - одна из них просто не может инициализироваться во время выполнения без каких-либо ошибок компиляции!

Например, если у меня есть:

class FooActivity {
    @Bind(R.id.foo) lateinit var mFoo: View
}
class NotFooActivity {
    @Bind(R.id.not_foo) lateinit var mFoo: View
}

Тогда один из них (или оба?) Просто не сможет инициализироваться без каких-либо ошибок. Вызов исключения kotlin.UninitializedPropertyAccessException: lateinit property mFoo has not been initialized при доступе к полю.


Это что-то, что я делаю неправильно при настройке Kotlin, или это ошибка kotlin?

Заранее спасибо! Рон

9
maxandron 25 Фев 2016 в 20:07

3 ответа

Лучший ответ

Оказался баг с kapt. Я опубликовал проблему в системе отслеживания ошибок Kotlin, и теперь проблема помечена как исправленная.

Это решение было объединено

Должно быть разрешено в Kotlin версии 1.0.2.

1
maxandron 7 Апр 2016 в 15:46

Итак, чтобы частично ответить на вопрос kotlin.UninitializedPropertyAccessException: lateinit, я столкнулся с тем же самым в моем проекте . Что я сделал, что «решило проблему» для меня, так это удалить Butterknife из класса-нарушителя, в данном случае это был просто viewHolder для моего нового расширяемого RecyclerView, а затем снова запустить приложение.

Запуск приложения после переключения всех моих @Bind(R.id.my_view_id) на "старую школу" findViewById(R.id.my_view_id) as MyViewType работал, но впоследствии я переключил тот же класс обратно на Butterknife и UninitializedPropertyAccessException ушел, и кажется, что он не вернется, если что-то в классе не изменится, тогда вам придется повторить этот процесс снова.

Я подозреваю, что это как-то связано с тем, что Kotlin не поддерживает инкрементную компиляцию, и каким-то образом, изменив автоматически сгенерированный код, он был вынужден перекомпилировать. Но я мог быть далеко отсюда, просто подумал, что поделюсь своим опытом.

0
Derek 28 Фев 2016 в 23:19

У меня возникла эта проблема, поэтому я начал ее исследовать, и это вызвано тем, что Kapt проверяет только имя метода при их сравнении, , и они добавляются в установлен , поэтому дублирование недопустимо. То же самое происходит с аннотированными полями, поэтому в настоящее время у вас может быть одно имя метода / поля для каждой аннотации.

Я добавил имя класса к методу equals, и теперь аннотации обрабатывались правильно, но тесты сломались, и я не знаю, как они работают, поэтому я надеюсь, что кто-то знает, как это исправить.

3
inorichi 20 Мар 2016 в 18:44