程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用

简介: 程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用

一. Dagger简介


Dagger 2 是 Google 开源的一款依靠注入结构,它的前身是 square 的 Dagger 1,Dagger 2 在 Android 中有着较为广泛的运用。


Dagger 2 根据 Java 注解,采用 annotationProcessor(注解处理器) 在项目编译时动态生成依靠注入需求的 Java 代码,然后咱们在合适的位置手动完结终究的依靠注入,而不是 Dagger 1 中根据反射的解决方案,所以在性能上是有保障的。


Android官方dagger介绍://代码效果参考:http://hnjlyzjd.com/xl/wz_24269.html


二. Dagger的依赖


// kapt is for implement annotation


apply plugin: 'kotlin-kapt'


// implementation dependences for dagger


implementation "com.google.dagger:dagger:2.21"


implementation "com.google.dagger:dagger-android-support:2.21"


kapt "com.google.dagger-compiler:2.21"


kapt "com.google.dagger-android-processor:2.21"


二. Dagger的配置


1. 初始化对象配置


1.1 使用@Inject注解初始化对象


注意:使用@Inject注解初始化对象时,构造函数所需的参数也必须已经使用dagger初始化,否则编译时会报错:com.record.sample.** cannot be provided without an @Inject constructor or an @Provides-annotated method


1 @Singleton


2 class RecordContractImple @Inject constructor(): RecordContract{


3   // empty body


4 }


1 @Singleton


2 class PicruteAdapter @Inject constructor(


3 context: Context


4 ): RecyclerView.Adapter{


5   // empty body


6 }


1.2 使用provide注解初始化对象


@Module


class RecordModule {


  @Provides


  @Singleton


  fun provideRecordAdapter(


    context: Context


  ): RecordAdapter = RecordAdapter(context)


  @Provides


  @Singleton


  fun provideRecordContract(


    recordContractImpl: RecordContractImpl  


  ): RecordContract = recordContractImpl


  @Provides


  @Singleton


  fun provideApplication(application: RecordApplication): RecordApplication = application


  @Provides


  @Singleton


  fun provideContext(application: RecordApplication): Context = application


}


使用@Named注解可以为同一个类初始化不同的对象,在页面中可以使用@Inject+@Named注解类使用该对象,但使用时一直报错: cannot be provided without an @Inject constructor or an @Provides-annotated method,原因未知。


// use @Named annotation to provide different instance for the same class


@Provides


@Singleton


@Named("Okhttp_client")


fun provideOkHttpClient(): OkHttpClient


@Provides


@Singleton


fun provideRetrofit(


  // use the @Named annotation to use different instance for same class


  @Named("Okhttp_client") okHttpClient: OkHttpClient


): Retrofit {


  return RetrofitProvide(...)


}


可以初始化基本类型


@Provider


fun provideAppVersion(): String = "2.21.0"


初始化Set,需要使用@ElementsIntoSet注解,网传dagger2.25以上版本有时候不需要显示提供@ElementsIntoSet注解。


@IntoSet注解告诉Dagger将返回的对象添加到Set依赖项中。


@Singleton


@Provides


@ElementsIntoSet


fun provideSet(): Set {


  val set = mutableSetOf()


  set.add("a")


  set.add("b")


  set.add("c")


  return set


}


@Singleton


@Provides


@ElementsIntoSet


fun provideSet2(): Set {


  val set = mutableSetOf()


  set.add("a")


  set.add("b")


  set.add("c")


  return set


}


@Provides


@IntoSet


fun provideInstanceForSet(): Name {


  return Name()


}


2. 绑定页面与使用Dagger初始化的对象


设置哪些页面可以使用@Inject方式获取Dagger初始化的对象。(ContributesAndroidInjector参数设置待确认)


@Module


interface BindRecordModule {


  @ContributesAndroidInjector


  fun bindMainActivity(): MainActivity


  @ContributesAndroidInjector


  fun bindHomeFragment(): HomeFragment


}


3. 定义Component配置moudle


将1和2中的配置配置到Component中,配置完点击make module后,Dagger会自动生成一个DaggerRecordComponent。


@Singleton


@Component(


  modules = 【


    // default module, must add


    AndroidSupportInjectionModule::class,  


    RecordModule::class,


    BindRecordModule::class,


  】


)


interface RecordComponent {


  @Component.Builder


  interface Builder {


    @BindsInstance


    fun application(application: Application): Builder


    fun build(): RecordComponent


  }


  fun inject(app: RecordApplication)


完成后点击Make Module,Dagger会自动生成类DaggerRecordComponent


4. 重写Application,配置Component


class RecordApplication: Application(), HasActivityInjector, HasSupportFragmentInjector {


  override fun onCreate() {


    DaggerRecordComponent.builder().


      .application(this)


      .build()


      .inject(this)


      super.onCreate()


  }


  @Inject


  internal lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector


  override fun activityInjector(): AndroidInjector {


    return activityDispatchingAndroidInjector


  }


  @Inject


  internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector


  override fun supportFragmentInjector(): AndroidInjector {


    return fragmentDispatchingAndroidInjector


  }


}


三. 使用


1. Activity中使用


AndroidInjection.inject(this)可以放在onAttach或者onCreate方法中初始化,只要在使用dagger初始化的地方之前调用即可。


HasSupportFragmentInjector可要可不要,原因未知。


class MainActivity: AppCompatActivity, HasSupportFragmentInjector {


  // use inject anotation to init instance, do not use private, otherwise the param will not init


  @Inject


  lateinit var recordContract: RecordContract


  override fun onCreate(savedInstanceState: Bundle?) {


    super.onCreate(savedInstanceState)


    // pass activity instance to dagger for init the param


    AndroidInjection.inject(this)


    // use the instance function directily


    val name = recordContract.getName()


  }


  @Inject


  internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector


  override fun supportFragmentInjector(): AndroidInjector {


    return fragmentDispatchingAndroidInjector


  }


}


2. Fragment中使用


AndroidSupportInjection.inject(this)可以放在onAttach或者onCreate方法中初始化,只要在使用dagger初始化的地方之前调用即可。


class HomeFragment: Fragment() {


  // use inject anotation to init instance, do not use private, otherwise the param will not init


  @Inject


  lateinit var recordContract: RecordContract    


  override fun onAttach(context: Context) {


    super.onAttach(context)


    // pass activity instance to dagger for init the param


    AndroidSupportInjection.inject(this)


  }


}


不断更新中,技术讨论可以留言,谢谢。


end

相关文章
|
27天前
|
安全 Java Android开发
05. 【Android教程】Android 程序签名打包
05. 【Android教程】Android 程序签名打包
18 1
|
23天前
|
存储 Java Android开发
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
16 2
|
3天前
|
安全 网络协议 网络安全
程序与技术分享:Android应用安全之数据传输安全
程序与技术分享:Android应用安全之数据传输安全
|
16天前
|
安全 网络安全 API
kotlin安卓开发JetPack Compose 如何使用webview 打开网页时给webview注入cookie
在Jetpack Compose中使用WebView需借助AndroidView。要注入Cookie,首先在`build.gradle`添加WebView依赖,如`androidx.webkit:webkit:1.4.0`。接着创建自定义`ComposableWebView`,通过`CookieManager`设置接受第三方Cookie并注入Cookie字符串。最后在Compose界面使用这个自定义组件加载URL。注意Android 9及以上版本可能需要在网络安全配置中允许第三方Cookie。
102 0
|
9天前
|
安全 Java Android开发
安卓开发中的新趋势:Kotlin与Jetpack的完美结合
【6月更文挑战第20天】在不断进化的移动应用开发领域,Android平台以其开放性和灵活性赢得了全球开发者的青睐。然而,随着技术的迭代,传统Java语言在Android开发中逐渐显露出局限性。Kotlin,一种现代的静态类型编程语言,以其简洁、安全和高效的特性成为了Android开发中的新宠。同时,Jetpack作为一套支持库、工具和指南,旨在帮助开发者更快地打造优秀的Android应用。本文将探讨Kotlin与Jetpack如何共同推动Android开发进入一个新的时代,以及这对开发者意味着什么。
|
5天前
|
Java 开发工具 Android开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
在移动应用开发的广阔天地中,Android和iOS两大平台各自占据着半壁江山。本文将深入探讨这两个平台在开发过程中的关键差异点,包括编程语言、开发工具、用户界面设计、性能优化以及市场覆盖等方面。通过对这些关键因素的比较分析,旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和目标受众做出明智的平台选择。
|
5天前
|
编解码 Android开发 iOS开发
深入探索Android与iOS开发的差异与挑战
【6月更文挑战第24天】在移动应用开发的广阔舞台上,Android和iOS两大操作系统扮演着主角。它们各自拥有独特的开发环境、工具集、用户基础及市场策略。本文将深度剖析这两个平台的开发差异,并探讨开发者面临的挑战,旨在为即将踏入或已在移动开发领域奋斗的开发者提供一份实用指南。
27 13
|
4天前
|
监控 Android开发 iOS开发
探索Android与iOS开发的差异:平台、工具和用户体验的比较
【6月更文挑战第25天】在移动应用开发的广阔天地中,Android和iOS两大平台各领风骚,它们在开发环境、工具选择及用户体验设计上展现出独特的风貌。本文将深入探讨这两个操作系统在技术实现、市场定位和用户交互方面的关键差异,旨在为开发者提供一个全景式的视图,帮助他们在面对项目决策时能够更加明智地选择适合自己项目需求的平台。
|
7天前
|
XML Java 开发工具
Android Studio开发Android TV
【6月更文挑战第19天】
|
4天前
|
缓存 测试技术 Shell
详细解读Android开发命令行完全攻略
详细解读Android开发命令行完全攻略