Kotlinx.android.synthetic неиспользуемая проблема студии Android

Я работаю над одним проектом, используя kotlin + Rxjava + MVVM. Во время разработки возникает проблема импорта идентификаторов представлений во фрагмент или вьюхолдер.

import kotlinx.android.synthetic.main.layout.* не используется с котлином.

Kotlinx.android.synthetic неиспользуемая проблема студии Android

Обычно идентификатор представления должен использоваться из импорта синтетического макета kotlin, но он напрямую импортирует его из R.id, чего не должно происходить.

Версия плагина Kotlin: org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.40

Мой файл Gradle:

apply plugin: 'com.android.feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'idea'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 27
    baseFeature true
    defaultConfig {
        minSdkVersion 23
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }


    lintOptions {
        abortOnError false
    }
}

dependencies {

    api "com.android.support:design:$rootProject.support_library_version"
    api "com.android.support:appcompat-v7:$rootProject.support_library_version"
    api "com.android.support:recyclerview-v7:$rootProject.support_library_version"
    api "com.android.support:support-dynamic-animation:$rootProject.support_library_version"
    api "com.android.support:cardview-v7:$rootProject.support_library_version"
    api "com.android.support:customtabs:$rootProject.support_library_version"

    api "com.android.support.constraint:constraint-layout:1.1.0-beta5"
    api 'android.arch.lifecycle:extensions:1.1.0'


    api 'androidx.core:core-ktx:0.2'


    api "com.google.dagger:dagger:$rootProject.dagger_version"
    kapt "com.google.dagger:dagger-compiler:$rootProject.dagger_version"

    api "android.arch.persistence.room:runtime:$rootProject.room_version"
    kapt "android.arch.persistence.room:compiler:$rootProject.room_version"
    testImplementation "android.arch.persistence.room:testing:$rootProject.room_version"
    api "android.arch.persistence.room:rxjava2:$rootProject.room_version"
    androidTestImplementation "android.arch.core:core-testing:$rootProject.room_version"
    testImplementation "android.arch.core:core-testing:$rootProject.room_version"

    api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"


    api 'com.jakewharton.timber:timber:4.5.1'

    api "com.android.support:multidex:1.0.3"

    api "com.github.bumptech.glide:glide:$rootProject.glide_version"
    api "jp.wasabeef:glide-transformations:$rootProject.glide_transformation_version"
    api 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'

    api "io.reactivex.rxjava2:rxandroid:$rootProject.rxAndroid_version"
    api "io.reactivex.rxjava2:rxjava:$rootProject.rxJava_version"
    api "com.google.code.gson:gson:$rootProject.gson_version"

    api("com.squareup.retrofit2:retrofit:$rootProject.retrofit_version") {
        // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
        exclude module: 'okhttp'
    }

    api "com.squareup.okhttp3:okhttp:$rootProject.okhttp_version"
    api "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttp_version"
    api "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofit_version"
    api "com.squareup.retrofit2:converter-gson:$rootProject.retrofit_version"

    api 'com.jakewharton.threetenabp:threetenabp:1.0.5'

    api "com.google.firebase:firebase-invites:$rootProject.play_services_version"
    api "com.google.firebase:firebase-core:$rootProject.play_services_version"
    api "com.google.firebase:firebase-config:$rootProject.play_services_version"
    api "com.google.firebase:firebase-perf:$rootProject.play_services_version"
    api "com.google.firebase:firebase-auth:$rootProject.play_services_version"
    api "com.google.firebase:firebase-firestore:$rootProject.play_services_version"



    api("com.firebaseui:firebase-ui-auth:$rootProject.firebase_ui_version") {
        // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
        exclude module: 'play-services-auth'
        exclude module: 'firebase-auth'
    }

    // Required only if Facebook login support is required
    api('com.facebook.android:facebook-android-sdk:4.31.0')

    api "com.google.android.gms:play-services-auth:$rootProject.play_services_version"

    // Required only if Twitter login support is required
    api("com.twitter.sdk.android:twitter-core:3.0.0@aar") { transitive = true }

    api 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.0.0'
    api 'com.jakewharton.rxbinding2:rxbinding-support-v4-kotlin:2.0.0'
    api 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7-kotlin:2.0.0'
    api 'com.jakewharton.rxbinding2:rxbinding-design-kotlin:2.0.0'

    api('com.crashlytics.sdk.android:crashlytics:2.9.1@aar') {
        transitive = true
    }
}

Я также пробовал чистую сборку и проект Rebuild.

Есть идеи, как я могу решить эту проблему?

Версия плагина должна быть 1.2.40, возможно, в этом проблема? Если нет, можете ли вы показать свои файлы build.gradle?

zsmb13 25.04.2018 08:33

Могу ли я узнать, что вы хотите видеть в файле Gradle?

Devganiya Hitesh 25.04.2018 08:35

Вы добавили apply plugin: 'kotlin-android-extensions'? а org.jetbrains.kotlin:kotlin-stdlib-jre7:?

IntelliJ Amiya 25.04.2018 08:36

Да уже добавлено

Devganiya Hitesh 25.04.2018 08:37

Покажите build.gradle, пожалуйста

IntelliJ Amiya 25.04.2018 08:38

да, поделитесь своим build.gradle

Shweta Chauhan 25.04.2018 08:39

Обновлены вопросы и добавлен мой файл gradle. Пожалуйста, проверь это.

Devganiya Hitesh 25.04.2018 09:13

Чтобы он работал в ViewHolder, вам необходимо включить экспериментальный режим и реализовать интерфейс LayoutContainer. (См. Эту ссылку). Вы это сделали?

reVerse 25.04.2018 09:42

LayoutContainer - это другой способ, но я его не использую

Devganiya Hitesh 25.04.2018 10:33

Но вы должны использовать его, чтобы он работал в ViewHolder. В противном случае у вас возникнут именно те проблемы, которые вы описываете. (Импорт статических идентификаторов)

reVerse 25.04.2018 10:42

Но та же проблема, с которой я также сталкиваюсь с фрагментами

Devganiya Hitesh 25.04.2018 10:49

У меня такая же проблема. И да, он правильно настроен и раньше работал нормально. Закрытие и повторное открытие Android Studio, похоже, решает проблему. Похоже на ошибку.

Danilo Prado 25.04.2018 17:00

Но проблема возникла снова неожиданно.

Devganiya Hitesh 26.04.2018 06:49

У меня такая же проблема, кажется, что в конце концов после создания файла R автоматически импортируется, что делает статический импорт представлений неиспользуемым. Синхронизация проекта решает эту проблему, но она возникает снова. Это происходит в двух разных проектах, так что похоже на баг студии Android.

Marcel 30.04.2018 10:12
23
14
10 709
10

Ответы 10

У меня такая же проблема, и я пытаюсь ее решить слишком много дней ...

Один из приемов, который вы можете сделать, - это использовать Исключить из импорта и завершения<package-name>.R.id.* для определения объема проекта.

Перейдите к Settings/Editor/Auto Import, чтобы добавить его.

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

ИЗМЕНИТЬ

Еще одно улучшение, которого я добился, - это работа с include на XML. Например, если я собираюсь использовать «одну и ту же» кнопку на нескольких экранах, я создаю определенный макет для этой кнопки и повторно использую его в нескольких действиях / фрагментах. Вы можете установить идентификатор в этом конкретном макете, и синтетический будет автоматически импортировать его без создания конфликтов, потому что у вас есть ссылка на представление содержимого, объявленная ранее.

Я покажу вам простой пример:

activity_main.xml

<!-- ... -->

<include layout = "@layout/btn_foo"/>

<!-- ... -->

btn_foo.xml

<?xml version = "1.0" encoding = "utf-8"?>
<Button
    android:id = "@+id/btnFoo"
    android:layout_width = "match_parent"
    android:layout_height = "wrap_content"
    xmlns:android = "http://schemas.android.com/apk/res/android"/>

MainActivity.kt

// ...

import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.btn_foo.*

// ...

setContentView(R.layout.activity_main)

// ...

btnFoo.setOnClickListener { }

Я должен признать, что в других случаях Я вернулся в типичное венгерское соглашение whatWhereDescription (Размер) для установки id из-за слишком раздражает, чтобы постоянно иметь дело с импортом между действиями / фрагментами / просмотром.

Да, это временное решение, и я тоже использую его.

Devganiya Hitesh 01.05.2018 07:53

Нет, @RickSanchez. Кроме того, я заметил, что если вы откроете другой экземпляр Android Studio, импорт сойдет с ума ... Я использую то, что я ответил ...

Gabi Moreno 14.05.2018 15:41

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

Тем не менее, наиболее близкое решение этой проблемы, которое сработало для меня до сих пор, - это удалить apply plugin: kotlin-android-extensions из gradle, плагин Sync gradle, а затем добавить его снова.

Хорошо, спасибо за ответ, проверим и сообщу вам.

Devganiya Hitesh 11.06.2018 05:49

Студия Android - это студия Android, но это сработало для меня

Gaurav Sarma 30.06.2019 21:16

Спасибо за решение, сэкономив много времени!

hetsgandhi 24.10.2019 14:13

@hetsgandhi Рад это знать :)

Wahib Ul Haq 24.10.2019 18:39

Я использую Android Studio 3.1.3 и столкнулся с той же проблемой. Мне удалось решить эту проблему, переместив все мои коды из java/ в каталог kotlin/ внутри main/.

app/
 |-- src/
 |    |-- main/
 |    |    |-- java/
 |    |    |     |-- com.example.android.app
 |    |    |-- kotlin/  <-- (use this)
 |    |    |     |-- com.example.android.app

Затем добавьте kotlin/ как часть исходных наборов:

приложение / build.gradle

android {
   sourceSets {
       main.java.srcDirs += 'src/main/kotlin'
   }
}

Иногда все еще требуется синхронизировать и перестроить проект, чтобы правильно импортировать kotlinx.android.....

Ссылка: Добавить код котлина

В трекере Google существует проблема (которая назначена) в отношении синтетического импорта. https://issuetracker.google.com/issues/78547457

Не знаю, споткнуло ли это кого-нибудь еще, но у меня были проблемы, потому что я не понимал, что синтетические объекты доступны только в том случае, если вы находитесь внутри Activity, Dialog или Fragment. Если вы находитесь в каком-то другом классе (например, используете Controller от Дирижер), вам не повезло.

Я тоже испытываю это с Дирижером. Я хотел бы придумать, как написать расширение kotlin для распознавания синтетических объектов для Conductor. Может кто-то указать мне верное направление?

ClayHerendeen 12.02.2019 17:20

Я решил аналогичные проблемы для реализаций ViewHolder:

Мы должны унаследовать нашу реализацию класса ViewHolder от LayoutContainer. LayoutContainer - это интерфейс, доступный в пакете kotlinx.android.extensions.

У вас будет код, похожий на этот:

class TaskVH(override val containerView: View, val itemListener: TasksFragment.TaskItemListener) : RecyclerView.ViewHolder(containerView), LayoutContainer {
    fun bindItem(task: Task) {
        item_title.text = ""
        item_complete.isChecked = task.isCompleted
        itemView.setBackgroundResource(rowViewBackground)
        itemView.setOnClickListener { itemListener.onTaskClick(task) }
    }
}

Хороший улов с LayoutContainer

oshurmamadov 14.08.2019 12:11

Для дирижера:

Создайте этот базовый класс.

import android.os.Bundle
import android.view.View
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.RestoreViewOnCreateController

abstract class BaseController(
        bundle: Bundle? = null
) : RestoreViewOnCreateController(bundle){

    init {
        addLifecycleListener(object : LifecycleListener() {
            override fun postCreateView(controller: Controller, view: View) {
                onViewCreated(view)
            }
        })
    }

    open fun onViewCreated(view: View) { }

}

Затем в вашем контроллере:

import kotlinx.android.synthetic.main.controller_example.view.*

class ProfileController : BaseController() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
        return inflater.inflate(R.layout.controller_example, container, false)
    }

    override fun onViewCreated(view: View) {     
        view.txtName.text = "Example"
    }

}

Кросс-публикация моего отчета об ошибке с обходным путем отсюда: https://issuetracker.google.com/issues/145888144

Исходная ошибка была закрыта Google как "исправленная", но определенно исправлена ​​нет: https://issuetracker.google.com/issues/78547457

РЕЗЮМЕ:

Для некоторых модулей в многомодульном проекте среда IDE не распознает должным образом импорт «синтетических» символов, которые абстрагируют идентификаторы представлений. Эта функция предоставляется подключаемым модулем kotlin-android-extensions. Это приводит к тому, что файлы классов, использующие эти символы, кажутся полными ошибок, поскольку импорт «неразрешен», символы тогда неизвестны, и, конечно же, все, что использует эти символы, терпит неудачу, потому что типы неизвестны. Однако это исключительно проблема IDE; все компилируется нормально и работает как положено.

ПЕРВОПРИЧИНА

Фасет котлинский язык не применяется к ошибочным модулям.

ЗАДНИЙ ПЛАН

Фасеты в проектах IntelliJ IDEA можно настраивать для каждого модуля в настройках проекта. В Android Studio эта часть пользовательского интерфейса настроек проекта отсутствует (или подавлена). Предположительно, Android Studio пытается применить правильные фасеты на основе плагинов gradle, примененных к каждому модулю. В данном конкретном случае этот процесс / иногда / НЕ ИСПОЛЬЗУЕТСЯ; Я не смог определить, что вызывает успех / неудачу процесса.

ВРЕМЕННОЕ РЕШЕНИЕ

Этот обходной путь работает стабильно, и, начиная с версии 3.5.2, когда я его обнаружил:

  1. Откройте файл «.iml» для модуля, который вы пытаетесь «исправить», в редакторе Android Studio. (В AS> 4 файл iml находится в .idea/modules, раньше, чем он был на верхнем уровне вашего модуля.) Найдите блок <component name = "FacetManager"> и обратите внимание, что там нет фасета, называемого «язык котлина». Вставьте содержимое текстового блока ниже, чтобы оно отображалось в блоке <component name = "FacetManager">. Сохраните файл.
  2. Повторно импортируйте gradle.

Это неуклюжий обходной путь, и его следует применять от модуля к модулю. Более того, иногда может потребоваться повторно применить обходной путь после внесения изменений в файл build.gradle для затронутого модуля. надеяться заключается в том, что Google (или JetBrains, если окажется, что это их проблема) исправит эту проблему должным образом.

Учитывая, что kotlin-android-extensions вышел из моды, я не думаю, что эта ошибка когда-либо будет исправлена.

Текст для исправления

    <facet type = "kotlin-language" name = "Kotlin">
      <configuration version = "3" platform = "JVM 1.8" allPlatforms = "JVM [1.8]" useProjectSettings = "false">
        <compilerSettings />
        <compilerArguments>
          <option name = "jvmTarget" value = "1.8" />
          <option name = "pluginOptions">
            <array>
              <option value = "plugin:org.jetbrains.kotlin.android:enabled=true" />
              <option value = "plugin:org.jetbrains.kotlin.android:defaultCacheImplementation=hashMap" />
            </array>
          </option>
        </compilerArguments>
      </configuration>
    </facet>

Я пробую любое другое решение, но у меня никто не работал. Я снова клонировал проект, и теперь он работает. Я люблю андроид студию

Добавьте идентификатор kotlin-android-extensions в свой файл build.gradle в блоке plugins.

Google удалил эту функцию по умолчанию

Другие вопросы по теме