J'essaie de démarrer un petit projet, en suivant une architecture propre, MVVM et en utilisant Retrofit, coroutines et autres. J'utilise Hilt pour DI et j'ai suivi à peu près ce que j'ai vu sur la documentation et d'autres projets.
Si j'annote mon activité ou mon fragment avec @AndroidEntryPoint ou l'application avec @HiltAndroidApp, l'application ne peut même pas démarrer. La trace de pile ne me dit pas grand-chose, mais peut-être que je saute quelque chose. Si je n'annote pas les classes, l'application essaie de démarrer, mais comme elle ne peut pas injecter le ViewModel de n'importe où, elle se bloque évidemment.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.searchspotify"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:name=".SearchSpotifyApp" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:screenOrientation="portrait" android:name=".presentation.view.activity.MainActivity" android:theme="@style/AppTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Je laisse ici une partie de mon code, si je dois fournir autre chose, faites le moi savoir, c'est assez basique pour le moment.
Application
private const val BASE_URL = "http://google.es" @Module @InstallIn(ApplicationComponent::class) object AppModule { @Singleton @Provides fun provideRetrofit(gson: Gson): Retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .build() @Provides fun provideGson(): Gson = GsonBuilder().create() @Provides fun provideSearchDataSource(retrofit: Retrofit): SearchDataSource = retrofit.create(SearchDataSource::class.java) @Singleton @Provides fun provideSearchRepository(searchDataSource: SearchDataSource) = SearchRepositoryImpl(searchDataSource) @Provides fun provideSearchViewModel(repository: SearchRepository) = SearchViewModel(repository) }
Activité
@AndroidEntryPoint class SearchFragment : Fragment() { private lateinit var binding: FragmentSearchBinding private val searchViewModel: SearchViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentSearchBinding.inflate(inflater) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { initViews() } private fun initViews() { searchViewModel.getSongs().observe(viewLifecycleOwner, { binding.text.text = it.first().title }) } }
Fragment
@AndroidEntryPoint class MainActivity: AppCompatActivity(){ private var binding: ActivityMainBinding? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView( this, R.layout.activity_main ) } override fun onDestroy() { binding = null super.onDestroy() } }
Module
@HiltAndroidApp class SearchSpotifyApp: Application(){ }
Je suis presque sûr qu'il me manque quelque chose de vraiment basique que je ne vois pas, car je ne suis pas familier avec la configuration de frameworks DI. Merci beaucoup d'avance.
Mise à jour: ajout du manifeste au cas où. Manifeste
Cause: com.example.searchspotify.presentation.view.activity.Hilt_MainActivity FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:transformClassesWithAndroidEntryPointTransformForDebug'. > javassist.NotFoundException: com.example.searchspotify.presentation.view.activity.Hilt_MainActivity * Exception is: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithAndroidEntryPointTransformForDebug'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:205) at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:203) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:184) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109) at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52) at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416) at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406) at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52) at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) Caused by: java.lang.RuntimeException: javassist.NotFoundException: com.example.searchspotify.Hilt_SearchSpotifyApp at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:108) at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104) at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42) at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:568) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394) at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:553) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:536) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:109) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:276) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:265) at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32) at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32) at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26) at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:63) at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35) at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49) at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34) at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43) at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73) at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54) at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34) at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44) at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54) at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38) at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49) at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:153) at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:67) at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:41) at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44) at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33) at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38) at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24) at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92) at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85) at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55) at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39) at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76) at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26) at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94) at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49) at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79) at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53) at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39) at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40) at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28) at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:192) ... 30 more Caused by: javassist.NotFoundException: com.example.searchspotify.Hilt_SearchSpotifyApp at javassist.ClassPool.get(ClassPool.java:430) at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformClass(AndroidEntryPointClassTransformer.kt:126) at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformClassToOutput(AndroidEntryPointClassTransformer.kt:105) at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformFile(AndroidEntryPointClassTransformer.kt:101) at dagger.hilt.android.plugin.AndroidEntryPointTransform.transformFile(AndroidEntryPointTransform.kt:156) at dagger.hilt.android.plugin.AndroidEntryPointTransform.transform(AndroidEntryPointTransform.kt:124) at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:284) at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:247) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106) ... 92 more
3 Réponses :
Ajoutez ceci ci-dessous dans votre fichier AndroidManifest.xml
<application android:name=".SearchSpotifyApp" </application>
C'est déjà là. J'ajoute le manifeste à la question au cas où.
Voici l'erreur dans votre code.
import androidx.hilt.lifecycle.ViewModelInject class SearchViewModel @ViewModelInject constructor( private val searchRepo: SearchRepository ) : ViewModel() { }
Pour injecter le ViewModel
, vous devez utiliser @ViewModelInject
annotation de androidx.hilt.lifecycle.ViewModelInject
package. Ainsi, votre code viewModel devrait ressembler à ceci
@Provides fun provideSearchViewModel(repository: SearchRepository) = SearchViewModel(repository)
Vous pouvez trouver les documents ici , et voici un exemple que j'ai créé.
@binkypv Cela a-t-il aidé?
Dans mon cas, j'ai oublié que j'utilise Kotlin et que j'utilise annotationProcessor. Je suis revenu à kapt et plus d'erreur.
Pouvez-vous également coller votre classe
SearchViewModel
?