I try to Hilt injection in RecyclerView Adapter but it throw me this error;
public final class RecyclerAdapterPhotos extends androidx.recyclerview.widget.RecyclerView.Adapter<com.packagename.projectName.RecyclerAdapters.RecyclerAdapterPhotos.PhotosVH> {
#AndroidEntryPoint base class must extend ComponentActivity, (support) Fragment, View, Service, or BroadcastReceiver.
Head My adapter.
#AndroidEntryPoint
class RecyclerAdapterPhotos(var context:Context, private val photoList:List\<PhotosModelItem\>):RecyclerView.Adapter\<RecyclerAdapterPhotos.PhotosVH\>() {
#Inject
lateinit var imageLoader:ImageLoaderHiltClass
...
override fun onBindViewHolder(holder: PhotosVH, position: Int) {
imageLoader.imageLoader(photoList[position].thumbnailUrl,holder.photosThumbnailVH)
...
Module of Picasso
#Module
#InstallIn(SingletonComponent::class)
object ImageLoaderModule {
#Provides
fun ProvidesImageLoader(photoUri:String,photoVH:ImageView):Picasso{
return Picasso.get()
}
I try to use Hilt for Picasso frame in my recyclerView adapter
Related
How get scope object (like ViewModel, Fragment etc where I inject) in injected object?
I finded only #ActivityContext annotation that give you activity but i need ViewModel
#HiltViewModel
class SomeViewModel #Inject constructor(
savedStateHandle: SavedStateHandle
) : ViewModel() {
#Inject lateinit var someObj: SomeInjectedObject
//some code
}
class SomeInjectedObject #Inject constructor(){
// how can i get here view model link ?
}
I can just set it in init block but it looks like incorrect decision
#HiltViewModel
class SomeViewModel #Inject constructor(
savedStateHandle: SavedStateHandle,
var someObj: SomeInjectedObject
) : ViewModel() {
init{
someObj.vm = this
}
//some code
}
class SomeInjectedObject #Inject constructor(){
var vm: ViewModel
}
I have a main activity as below:
#AndroidEntryPoint
class MainActivity : BaseActivity() {
#Inject
lateinit var configuration: Configuration
...
}
And a module defined like:
#Module
#InstallIn(SingletonComponent::class)
class AppModules {
#Singleton
#Provides
fun bindDeviceConfig(): Configuration {
return Configuration()
}
}
When I try running this it gives an error:
lateinit property configuration has not been initialized
I've looked at the documentation and can't seem to get my head around why I'm getting this issue. Does anyone know why?
The Code A is from the aritcle https://developer.android.com/training/dependency-injection/hilt-android
In my mind, a abstract class can not include non-abstract class .
But the function abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl): AnalyticsService accept a non-abstract class parameter, why?
Code A
interface AnalyticsService {
fun analyticsMethods()
}
// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl #Inject constructor(
...
) : AnalyticsService { ... }
#Module
#InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {
#Binds
abstract fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl
): AnalyticsService
}
I'm trying to understand Dagger. I created applicationInjector class :
class BaseApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication>? {
return DaggerAppComponent.builder().application(this)?.build()
}
}
And here's my AppComponent
#Component(
modules = [AndroidSupportInjectionModule::class,
ActivityBuilderModules::class]
)
interface AppComponent : AndroidInjector<BaseApplication> {
#Component.Builder
interface Builder {
#BindsInstance
fun application(application: Application?): Builder?
fun build(): AppComponent?
}
}
Now what I want to do is to to inject simple String to Activity (really basic, right ?)
In Java it works like this :
#Module
abstract class ActivityBuilderModules {
#ContributesAndroidInjector
abstract fun contributeAuthActivity() : AuthActivity
//JAVA
#Provides
public static String provideTestString() {
return "TEST "
}
however we don't have static function in Kotlin, right ? And it needs to be static cause I'm getting an error :
error: com.example.kotlintests.di.ActivityBuilderModules is abstract and has instance #Provides methods. Consider making the methods static or including a non-abstract subclass of the module instead.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.kotlintests.BaseApplication> {
I tried with package level function but it didn't work. How can I add provideTestString function in Kotlin ?
I'm confused by this Kotlin error associated with providing an implementation for an abstract class that has been imported from a maven package.
I have a maven library that is written in Kotlin and exposes an abstract class called APIGatewayRequestHandler. In my app that imports the library, I provide an implementation of the abstract class:
class GetWelcomeMessageHandler : APIGatewayRequestHandler<WelcomeMessage>()
fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): WelcomeMessage {
return WelcomeMessage()
}
}
The decompiled abstract class from the library looks like this:
public abstract class APIGatewayRequestHandler<T> public constructor() : com.amazonaws.services.lambda.runtime.RequestHandler<com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, T> {
public abstract fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): T
public open fun handleRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent?, context: com.amazonaws.services.lambda.runtime.Context?): T {
/* compiled code */
}
}
I get the following error:
Class 'GetWelcomeMessageHandler' is not abstract and does not implement abstract base class member
public abstract fun handleAPIGatewayRequest(input: APIGatewayProxyRequestEvent, context: Context?): WelcomeMessage
I think you're just missing some override keywords. Namely, your abstract class should have it on the handleRequest method:
public abstract class APIGatewayRequestHandler<T> public constructor() : com.amazonaws.services.lambda.runtime.RequestHandler<com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, T> {
public abstract fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): T
public override fun handleRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent?, context: com.amazonaws.services.lambda.runtime.Context?): T {
/* compiled code */
}
}
And then your GetWelcomeMessageHandler should have it on its handleAPIGatewayRequest method:
class GetWelcomeMessageHandler : APIGatewayRequestHandler<WelcomeMessage>() { // <-- This curly brace was also missing
override fun handleAPIGatewayRequest(input: com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent, context: com.amazonaws.services.lambda.runtime.Context?): WelcomeMessage {
return WelcomeMessage()
}
}