kotlinx.android.synthetic未使用的android studio问题

时间:2018-04-25 06:32:49

标签: android android-studio mvvm kotlin

我正在使用kotlin + Rxjava + MVVM开发一个项目。在开发过程中面临在Fragment或viewholder中导入视图ID的问题。

import kotlinx.android.synthetic.main.layout.*与kotlin一起使用。

kotling synthetic imports is unused

Normaly view id应该从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
    }
}

我也尝试了干净的构建和重建项目。

我知道如何解决这个问题?

10 个答案:

答案 0 :(得分:6)

我正在使用Android Studio 3.1.3,并且遇到了相同的问题。通过将所有代码从java/移到kotlin/内的main/目录中,我设法解决了这一问题。

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

然后,将kotlin/添加为源集的一部分:

app / build.gradle

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

有时候,仍然需要同步并重建项目以正确导入kotlinx.android....

参考:Add kotlin code

答案 1 :(得分:4)

我尝试了几种方法,包括此主题中报告的解决方案。我还发现很多人都面临着这个恼人的问题,你可以看到here

尽管如此,迄今为止对我来说最有效的解决方案是从gradle,apply plugin: kotlin-android-extensions gradle插件中移除Sync,然后重新添加。

答案 2 :(得分:2)

我有同样的问题,我试图解决它太多天了......

您可以做的一件事就是从导入和完成中排除 <package-name>.R.id.*以获取项目范围。

转到Settings/Editor/Auto Import添加。

它改善了我们的问题,如果你这样做并清理项目,它会起作用,但它不能完全解决问题。很多时候,进口重新出现为未使用的进口,并且要反复清理项目: - (。

<强> EDITED

此外,我所取得的另一项改进是使用include来处理XML。例如,如果我要使用&#34;相同的&#34;在几个屏幕上的按钮,我为这个按钮做了一个特定的布局,我在几个活动/片段上重复使用它。您可以在此特定布局中设置id,并且合成将自动导入它而不会产生冲突,因为您具有之前声明的内容视图引用。

我给你举了一个简单的例子:

<强> 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(Size)来设置id s在活动/片段/视图中一直处理导入太烦人了。

答案 3 :(得分:0)

Google跟踪器上存在有关合成进口的现有问题(已分配)。 https://issuetracker.google.com/issues/78547457

答案 4 :(得分:0)

我不知道这是否会使其他人绊倒,但是我遇到了问题,因为我没有意识到只有在ActivityDialog内,合成对象才可用,或Fragment。如果您在其他班级(例如使用ConductorController),那么您就不走运了。

答案 5 :(得分:0)

我已经为ViewHolder实现解决了类似的问题:

我们必须从LayoutContainer继承ViewHolder类的实现。 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) }
    }
}

答案 6 :(得分:0)

对于导体:

创建此基类。

from jwcrypto import jwk, jwe

encrypted_token = request.cookies.get(cookie_name)  

key = jwk.JWK.from_json('{"kty":"oct","k":"TWJQZVNoVm1ZcTN0Nnc5eg"}')

jwe_token = jwe.JWE()
jwe_token.deserialize(encrypted_token)
jwe_token.decrypt(key)
decrypted_payload = jwe_token.payload

然后在您的控制器中:

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) { }

}

答案 7 :(得分:0)

从此处交叉发布我的错误报告和解决方法:https://issuetracker.google.com/issues/145888144

原始错误已被Google修复为“已修复”,但绝对未得到 修复:https://issuetracker.google.com/issues/78547457

摘要:

对于多模块项目中的某些模块,IDE无法正确识别抽象视图ID(插件“ kotlin-android-extensions”提供的功能)的“合成”符号的导入。这导致使用这些符号的类文件看起来充满错误,因为导入是“未解决的”,因此这些符号是未知的,当然使用这些符号的任何操作都会失败,因为类型是未知的。一切都能正常编译并按预期工作。

根本原因

kotlin语言方面未应用于错误的模块。

背景

可以在项目设置中逐模块配置IntelliJ IDEA项目中的Facet。在Android Studio中,项目设置UI的这一部分丢失(或取消显示)。大概是,Android Studio尝试基于应用于每个模块的gradle插件来应用正确的构面。对于特定情况,此过程有时会失败。我无法确定是什么触发了该过程的成功/失败。

临时解决方法

此替代方法在大多数情况下都对我有效,并且自从3.5.2发现以来一直存在:

  1. 找到您的其中一个Android扩展IDE集成正在工作的模块。如果它们都不起作用,那么您将无法正常工作。
  2. 导入gradle(确保它是最新的)。保持项目开放
  3. 使用文本编辑器(不是 Android Studio!),打开在步骤1中标识的模块的“ .iml”文件。(例如,“ library / library.iml”),您将找到它是一个XML文件。将指定为<facet type="kotlin-language" name="Kotlin">的整个块复制到剪贴板。
  4. 使用文本编辑器,为您要“修复”的模块打开“ .iml”文件。找到<component name="FacetManager">块,然后注意到那里没有称为“ kotlin语言”的构面。粘贴剪贴板中的内容,使其出现在<component name="FacetManager">块中。保存文件。
  5. 重新导入gradle。

在重新导入gradle之后的大部分时间里,这会使我添加的构面保持原样,并且视图ID的IDE插件集成已开始对该模块起作用。

这是一个笨拙的解决方法,必须逐模块应用。此外,在更改了受影响模块的build.gradle文件后,有时可能需要重新应用变通方法。 希望是Google(或JetBrains,如果事实证明是他们的问题)会正确解决此问题。

答案 8 :(得分:0)

我尝试其他所有解决方案,但没有人为我工作。在,我再次克隆了项目,现在它可以正常工作了。我爱android studio

答案 9 :(得分:0)

kotlin-android-extensions块的build.gradle文件中添加ID plugins

Google默认删除了此功能