当前位置: 首页 > 知识库问答 >
问题:

Android Kotlin Hilt:构建项目时出错

孔波
2023-03-14

我是Hilt的新手,我正在努力在我的多模块应用程序中实现它。经过无限次尝试,构建错误从“错误a”到“错误b”,然后是“错误c”等等。

这就是我如何开始在我的多模块应用程序中实现希尔特:

Project build.gradle:

buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath("com.google.dagger:hilt-android-gradle-plugin:2.42")
    }
    ext.java_version = JavaVersion.VERSION_1_8
}

allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven { url "https://jitpack.io" }
        maven { url 'https://repository-achartengine.forge.cloudbees.com/snapshot/' }
        maven { url 'def androidHome = System.getenv("ANDROID_HOME")' }
        maven { url "/Home/Diego/Android/Sdk/extras/android/m2repository/" }
        google()
    }
}

应用程序build.gradle:

plugins {
    id('dagger.hilt.android.plugin')
    id('com.android.application')
    id('kotlin-android')
    id('kotlin-kapt')
}

android {
    compileSdkVersion 32
    def code
    Properties versionProps = new Properties()
    def versionPropsFile = file('version.properties')
    if (versionPropsFile.exists())
        versionProps.load(new FileInputStream(versionPropsFile))
    code = (versionProps['VERSION_CODE'] ?: "0").toInteger() + 1
    versionProps['VERSION_CODE'] = code.toString()
    versionProps.store(versionPropsFile.newWriter(), null)
    packagingOptions {
        resources {
            pickFirsts += ['META-INF/LICENSE.txt']
            excludes += ['META-INF/NOTICE.md', 'META-INF/LICENSE.md', 'META-INF/INDEX.LIST', 'META-INF/DEPENDENCIES', 'META-INF/io.netty.versions.properties']
        }
    }
    defaultConfig {
        applicationId 'com.xxx.xxx'
        minSdkVersion 23
        targetSdkVersion 32
        versionCode code
        versionName "2.0." + code
        // next ndk abifilters have to be disabled if spli apk is enabled.
        // ndk.abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'//testing
        multiDexEnabled true
        compileOptions {
            sourceCompatibility java_version
            targetCompatibility java_version
        }
    }
    compileOptions {
        sourceCompatibility java_version
        targetCompatibility java_version
    }
    splits {
        // Configures multiple APKs based on ABI.
        abi {
            // Enables building multiple APKs per ABI.
            enable true
            // By default all ABIs are included, so use reset() and include to specify that we only
            // want APKs for x86 and x86_64.
            // Resets the list of ABIs that Gradle should create APKs for to none.
            reset()
            // Specifies a list of ABIs that Gradle should create APKs for.
            include "armeabi-v7a"
            include "arm64-v8a"
            include "x86"
            include "x86_64"
            // Specifies that we do not want to also generate a universal APK that includes all ABIs.
            universalApk false
        }
    }
    buildTypes {
        release {
            /*signingConfig signingConfigs.release*/
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // This next piece of code is used by apk Split
            applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    project.ext { appName = 'xxx' }
                    def newName = 'xxx_' + output.getFilter(com.android.build.OutputFile.ABI) + '.apk'
                    outputFileName = new File("./", newName)
                }
                // assign different version code for each output
                variant.outputs.each { output ->
                    output.versionCodeOverride =
                            //project.ext.versionCodes.get(output.getFilter(OutputFile.ABI)) * 1000 + android.defaultConfig.versionCode
                            project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI)) * 1000 + code - 1000
                }
            }
        }
        debug {
        }
    }
    allprojects {
        repositories {
            jcenter()
            mavenCentral()
            def androidHome = System.getenv("ANDROID_HOME")
            maven {
                url "$androidHome/extras/android/m2repository/"
            }
            maven {
                url "https://maven.java.net/content/groups/public/"
            }
        }
        /*tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }*/
    }
    productFlavors {
    }
    androidResources {
        ignoreAssetsPattern '!*ffprobe'
    }
    lint {
        abortOnError false
        checkReleaseBuilds false
    }
    dataBinding{
        enabled = true
    }
    namespace 'com.xxx.xxx'
}

// This next piece of code is used by apk Split
// map for the version code that gives each ABI a value. make sure to list all ABIs mentioned in splits block, an keep the order.
ext.versionCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4]
//import com.android.build.OutputFile

dependencies {
    //P7Zip
    //implementation 'com.hzy:libp7zip:1.7.0'
    //Apache Commons
    //implementation 'commons-io:commons-io:2.6'
    //ffmpeg
    implementation 'com.arthenica:mobile-ffmpeg-min-gpl:4.2.2.LTS'
    //implementation 'com.arthenica:mobile-ffmpeg-full:4.3.1'
    //Google Guava
    api 'com.google.guava:guava:31.1-jre'
    //volley
    api 'com.android.volley:volley:1.2.1'
    //spotify
    api 'com.github.kaaes:spotify-web-api-android:0.4.1'
    //mail API 19
    //api 'com.sun.mail:android-mail:1.6.4'
    //api 'com.sun.mail:android-activation:1.6.4'
    //mail API 16
    //api 'com.sun.mail:android-mail:1.6.7'
    //api 'com.sun.mail:android-activation:1.6.7'
    //apache commons lang
    //ppppapi 'org.apache.commons:commons-lang3:3.12.0'
    implementation group: 'org.apache.commons', name: 'commons-text', version: '1.9'
    //Font Selector List Preference
    api 'com.vanniktech:vntfontlistpreference:1.0.0'
    //Rate my app
    api 'com.github.hotchemi:android-rate:1.0.1'
    //Support
    api 'androidx.appcompat:appcompat:1.4.2'
    api 'androidx.legacy:legacy-support-v4:1.0.0'
    //AlertDialog
    implementation 'com.github.d-max:spots-dialog:1.1@aar'
    //glide animated gifs
    implementation 'com.github.bumptech.glide:glide:4.13.2'
    implementation 'androidx.viewpager2:viewpager2:1.0.0'
    implementation project(path: ':Common')
    annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    //preference
    implementation 'androidx.preference:preference-ktx:1.2.0'
    //
    api 'com.rockerhieu:rv-adapter-endless:1.2'
    implementation 'com.squareup.picasso:picasso:2.71828'
    //flat-dialog
    implementation 'com.github.mejdi14:Flat-Dialog-Android:1.0.5'
    //Hilt
    //implementation('com.google.dagger:hilt-android:2.40')
    //annotationProcessor('com.google.dagger:hilt-android-compiler:2.40')

    implementation 'com.google.dagger:hilt-android:2.42'
    //implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0'
    //implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    //annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0'
    kapt 'com.google.dagger:hilt-android-compiler:2.42'
    kapt('org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0')

    implementation project(':Common')
    implementation project(':DTO')
    implementation project(':Core')
}

// Allow references to generated code
kapt {
    correctErrorTypes = true
}

考虑到这一点,我必须提到我有一个AppSettings类,在那里我存储了所有的应用程序配置(现在我已经创建了AppSettings1只是为了测试),开始时我试图将该类注入到主活动中,这样它的所有变量都可用。

主要活动:

@AndroidEntryPoint
class MainActivity @Inject constructor(private val appSettings: AppSettings1): FragmentActivity(), IActionListeners, IImageListeners, OnListFragmentInteractionListener
{
val color2 = appSettings.infoAlertBkgColor
...
}

主视图模型:

@HiltViewModel
@SuppressLint("StaticFieldLeak")
class MainViewModel
@Inject constructor(@ApplicationContext var context: Context, private val appSettings: AppSettings1) : ViewModel() {
...
}

应用程序设置:

@HiltAndroidApp
class AppSettings1 : MultiDexApplication() {

    val infoAlertBkgColor1 = "#60a69e"

    override fun onCreate() {
        super.onCreate()
        //instance = this
        resourses = applicationContext.resources
        outputPathCache = cacheDir.absolutePath
    }
}

当我构建应用程序时,下一个错误出现了:

/Users/diego/StudioProjects/artandwords/app/build/generated/hilt/component_sources/debug.com/artandwords/thoughtofday/app/AppSettings1_HiltComponents。java:127:错误:[Dagger/MissingBinding]com.xxx.xxx.app。如果没有@Inject构造函数或@Provides注释方法,则无法提供AppSettings1。公共抽象静态类SingletoC实现AppSettings1_GeneratedInjector,^com.xxx.xxx.app的绑定。AppSettings1存在于com.xxx.xxx.app.AppSettings1_HiltComponents中。单个C:com.xxx.xxx.app。AppSettings1在[com.xxx.xxx.app.AppSettings1_HiltComponents.ViewModelC]com.xxxx.xxx.activities.main注入。MainViewModel(…,appSettings)com.xxx.xxx.activities.main。MainViewModel在[com.xxx.xxx.app.AppSettings1_HiltComponents.ViewModelC]com.xx.xxx.activities.main.MainViewModel_HiltModules.BindsModule注入。绑定(arg0)@dagger.hilt.android.internal.lifecycle。希尔顿视图模型地图java.util.Map

顺便说一下,我的应用程序是一个多模块的,所以我想我必须在每个模块上安装刀柄依赖和插件(就像我已经做的那样),对吗?

我坚持说我是新手,所以很可能我做错了什么,但却不知道是什么。

有什么帮助吗?

共有2个答案

东门理
2023-03-14
@AndroidEntryPoint
class MainActivity 
/*Not allowed*/
@Inject constructor(private val appSettings: AppSettings1): FragmentActivity()
...
}

首先,对于像 Activity 这样的 android 类,您不能将构造函数注入用于自定义参数/依赖项。如果需要,可以改用场注入。

@AndroidEntryPoint
class MainActivity (): FragmentActivity(){
    //Sample field injection
    @Inject lateinit var dependencyClass: DependencyClass
..
}

其次,您不需要将Application类注入活动,您可以使用应用程序getApplication()访问它,例如:

/*Cast `application` to the
 * actual application class to access its field.
 */
 val color2 = (application as AppSettings1).infoAlertBkgColor1 
田永春
2023-03-14

你的AppSettings1是一个继承自Application类的类,而Hilt不知道它到底是什么以及如何注入它——它就像一个未知的实体。你必须创建一个模块来告诉Hilt如何与之合作(在这种情况下是不可能的,因为你不能删除@HiltAndroidApp ),因此唯一的方法就是next

@HiltAndroidApp
class AppSettings1 @Inject constructor : MultiDexApplication()

之后,您可以将其注入VM中

@Inject constructor(@ApplicationContext var context: Context, private val app: AppSettings1) : ViewModel() {
...

但有几件事你应该考虑

  1. 你可以从 applicationContext 中获取任何你想要的资源,你不需要专门使用 App 类本身。您的@ApplicationContext变量上下文:上下文绰绰有余。
  2. 从应用上下文/应用中检索资源是一个坏主意。例如,您正在切换主题并重新创建所有活动 - 但不是应用程序类,因此您仍将拥有资源的旧引用,并且所有 UI 内容都将具有错误的颜色主题。
 类似资料:
  • 新安装的android工作室,并开始新的Android项目。当试图运行它时。从Gradle那里得到这个错误 我尝试过重建项目,也尝试过删除文件夹,但没有任何效果。

  • mvn-版本 Apache Maven 3.6.1(d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555;2019-04-04T21:00:29 02:00)Maven主页:C:\Apps\Apache-Maven-3.6.1\bin。。Java版本:11.0.13,供应商:Oracle Corporation,运行时:C:\Apps\jdk-11.0.13_windo

  • 当我打开我的项目并且Eclipse尝试构建它时,我收到了这个错误:在“构建工作区”期间发生了一个内部错误。java.lang.StackOverflowError. 它仍然完成构建(我想),我可以继续。但是我收到一个“内部错误”弹出窗口,说发生了堆栈溢出,建议我退出工作台。我只是忽略了弹出窗口。 以下是我的.log输出: 我该怎么做才能避免这个问题?

  • 当我在windows上使用gradle构建示例corda项目(gradlew.bat deployNodes)时,我在log4j中看到了关于删除命令的错误: 2019-10-28 16:30:47207主要错误删除包含无效属性“IfFileName”、“IfLastModified”2019-11-28 16-30:47213主要错误缺少删除条件:不支持无条件删除2019-12-28 16:30: