安卓+Kotlin+剑柄:生成项目时出错

fdbelqdn  于 2022-12-13  发布在  Kotlin
关注(0)|答案(2)|浏览(106)

我是Hilt的新手,为了在我的多模块应用程序中实现它,我绞尽脑汁。在无数次尝试之后,构建错误从“错误a”到“错误b”,然后是“错误c”等等。
这就是我开始在我的多模块应用中实现Hilt的方式:

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

应用构建器.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类,我在其中存储了所有应用配置(现在我创建了AppSettings 1,只是为了测试),并且首先我尝试将该类注入到主Activity中,以便它的所有变量都可用。
主要活动:

@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
    }
}

当我构建应用程序时,会抛出下一个错误:
/用户/diego/studioProjects/艺术和文字/应用程序/构建/生成/hilt/组件源/调试/com/艺术和文字/今天的想法/应用程序/应用程序设置1_HiltComponents.java:127:错误:[Dagger/MissingBinding]如果没有@Inject构造函数或@ Provides注解的方法,则无法提供com. xxx. xxx. app. AppSettings 1。公共抽象静态类SingletonC实现AppSettings1_GeneratedInjector,^com. xxx. xxx. app. AppSettings 1的绑定存在于com. xxx. xxx. app. AppSettings1_HiltComponents.SingletonC中:在[com.xxx.xxx.app.AppSettings1_HiltComponents.ViewModelC] com.xxx.xxx.活动.主视图模型中注入了应用程序设置1(...,应用程序设置)com.xxx.xxx.活动.main.主视图模型被注入到[com. xxx. xxx.应用程序.应用程序设置1_HiltComponents.ViewModelC] com.xxx.xxx.活动.main.主视图模型_HiltModules.绑定请访问下面的网址,查看您的浏览器配置文件<androidx.lifecycle.ViewModel>。[com. xxx. xxx.应用程序.应用程序设置1_Hilt组件.单点C → com. xxx. xxx.应用程序.应用程序设置1_Hilt组件.活动保留C → com. xxx. xxx.应用程序.应用程序设置1_Hilt组件.视图模型C]
顺便说一句,我的应用程序是一个多模块的,所以我想我必须在每个模块上安装Hilt依赖项和插件(就像我已经做的那样),对吗?
我是新手,所以很可能我做错了什么。接下来我该怎么做?

uklbhaso

uklbhaso1#

你的AppSettings 1是一个继承自Application类的类,Hilt不知道它到底是什么,也不知道如何注入它--它就像一个未知的实体。你要么创建一个模块,告诉Hilt如何与它合作(在这种情况下是不可能的,因为你不能删除@HiltAndroidApp),因此唯一的方法是下一步

@HiltAndroidApp
class AppSettings1 @Inject constructor : MultiDexApplication()

之后,您可以将其注入虚拟机

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

但有几件事你应该考虑
1.您可以从applicationContext中获取任何所需的资源,而不需要App类本身,您的@ApplicationContext var context: Context就足够了。
1.从应用上下文/应用中检索资源是个坏主意。例如,您切换主题,所有Activity都被重新创建-但应用类没有被重新创建,因此您仍将拥有资源的旧引用,所有UI内容都将使用错误的颜色主题。

w9apscun

w9apscun2#

@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类注入到Activity,您可以使用applicationgetApplication()访问它,例如:

/*Cast `application` to the
 * actual application class to access its field.
 */
 val color2 = (application as AppSettings1).infoAlertBkgColor1

相关问题