a284628487 / AndroidPoint

Android Note
1 stars 0 forks source link

Android Hilt #15

Open a284628487 opened 3 years ago

a284628487 commented 3 years ago

Component

ActivityComponent

定义ActivityComponent模块

interface IApi {

    fun sayHello()
}

class IApiImpl @Inject constructor(@ActivityContext private val context: Context) : IApi {

    override fun sayHello() {
        Log.e("IApiImpl${this.hashCode()}", "sayHello ${context}")
    }
}

@Module
@InstallIn(ActivityComponent::class)
abstract class ApiModule {

    @Binds
    abstract fun bindApi(apiImpl: IApiImpl): IApi
}

在Activity中注入

@AndroidEntryPoint
class TestActivity: AppCompatActivity() {

    @Inject lateinit var iApi: IApi
    @Inject lateinit var iApi2: IApi
}

class Test2Activity: AppCompatActivity() {

    @Inject lateinit var iApi: IApi
}

TestActivityTest2Activity中获取到的IApi对象为不同的实例。 TestActivityiApiiApi2也是不同的实例对象。

SingletonComponent、Singleton

修改IApiImpl和ApiModule,将IApiImpl修改为单例实现。

@Singleton
class IApiImpl @Inject constructor(@ApplicationContext private val context: Context) : IApi {

    override fun sayHello() {
        Log.e("IApiImpl${this.hashCode()}", "sayHello ${context}")
    }
}

@Module
@InstallIn(SingletonComponent::class)
abstract class ApiModule {

    @Binds
    abstract fun bindApi(apiImpl: IApiImpl): IApi
}
a284628487 commented 3 years ago

Scope

ActivityScoped

class SayHelloAdapter @Inject constructor(val activity: Activity) {

    fun sayHello() {
        Log.e("SayHelloAdapter${this.hashCode()}", "sayHello ${activity}")
    }
}

@AndroidEntryPoint
class TestActivity: AppCompatActivity() {

    @Inject lateinit var adapter: SayHelloAdapter

    @Inject lateinit var adapter2: SayHelloAdapter
}

在没有其它额外的Scope定义的时候,上面在同一Activity中注入的两个Adapter,会生成两个不同的对象实例。

修改Adapter的定义,添加ActivityScoped

@ActivityScoped
class SayHelloAdapter @Inject constructor(val activity: Activity) {

    fun sayHello() {
        Log.e("SayHelloAdapter${this.hashCode()}", "sayHello ${activity}")
    }
}

在添加了ActivityScoped后,上述同一Activity中注入的两个adapter,为同一实例。 如果在另外一个Activity注入Adapter,则会重新生成一个不同的实例。

a284628487 commented 3 years ago

Qualifier

interface INetApi {

    fun sayHello()
}

// INetApiGitLabImpl
@Singleton
class INetApiGitLabImpl @Inject constructor(@ApplicationContext private val context: Context) : INetApi {

    override fun sayHello() {
        Log.e("INetApiGitLabImpl${this.hashCode()}", "sayHello ${context}")
    }
}

// INetApiGithubImpl
@Singleton
class INetApiGithubImpl @Inject constructor(@ApplicationContext private val context: Context) : INetApi {

    override fun sayHello() {
        Log.e("INetApiGithubImpl${this.hashCode()}", "sayHello ${context}")
    }
}

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IApiInstanceGithub

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IApiInstanceGitLab

使用Binds提供INetApi


@Module
@InstallIn(SingletonComponent::class)
abstract class ApiModule {

    @Binds
    @IApiInstanceGithub
    abstract fun bindGithubApi(apiImpl: INetApiGithubImpl): INetApi

    @Binds
    @IApiInstanceGitLab
    abstract fun bindGitLabApi(apiImpl: INetApiGitLabImpl): INetApi
}

在Activity中注入

@AndroidEntryPoint
class TestActivity: AppCompatActivity() {

    @IApiInstanceGithub
    @Inject lateinit var iNetApi1: INetApi
    @IApiInstanceGitLab
    @Inject lateinit var iNetApi2: INetApi
}

使用Provides提供

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

  @AuthInterceptorOkHttpClient
  @Provides
  fun provideAuthInterceptorOkHttpClient(
    authInterceptor: AuthInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(authInterceptor)
               .build()
  }

  @OtherInterceptorOkHttpClient
  @Provides
  fun provideOtherInterceptorOkHttpClient(
    otherInterceptor: OtherInterceptor
  ): OkHttpClient {
      return OkHttpClient.Builder()
               .addInterceptor(otherInterceptor)
               .build()
  }
}

// 作为其它类的依赖项
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {

  @Provides
  fun provideAnalyticsService(
    @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
  ): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .client(okHttpClient)
               .build()
               .create(AnalyticsService::class.java)
  }
}

// 作为其它类的构造函数依赖项
class ExampleServiceImpl @Inject constructor(
  @AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient
) : ...

// 字段注入
@AndroidEntryPoint
class ExampleActivity: AppCompatActivity() {

  @AuthInterceptorOkHttpClient
  @Inject lateinit var okHttpClient: OkHttpClient
}