☰
Dagger Android 简单示例深度解析:用 ObjectGraph 与自定义 Application 构建全局依赖图
2026/9/28 7:16:27 网站建设 项目流程
  • 依赖注入
  • 移动开发
  • 后端

【免费下载链接】dagger

A fast dependency injector for Android and Java.

项目地址:https://gitcode.com/gh_mirrors/dag/dagger
点击查看免费下载

本指南以仓库 examples/android-simple 示例为骨架,系统讲解 Dagger(dagger 1.x 时代核心 API)在 Android 应用中的落地方式:如何用自定义Application维护全局ObjectGraph、如何用可覆写的getModules()实现开发版/测试环境的模块扩展,以及如何在基类 Activity 中自动完成注入。读完你将掌握一套可直接套用的 Android + Dagger 最小工程结构,并理解其中每个注解与配置的底层语义。

示例定位:展示结构而非业务功能

README.md 开篇即明确了该示例的边界:它演示的是"如何用 Dagger 组织一个 Android 应用",而不是一个可运行的业务 App。原文特别说明:应用运行时不会真正做任何事,它只是展示如何把 Dagger 结构化地嵌入 Android 工程。因此阅读本文时,关注点应放在依赖注入的装配模式上,而非 Activity 里的具体逻辑。

核心模式一句话概括:用自定义Application类管理一个全局对象图(Object Graph),模块通过 Application 上的getModules()方法装配,该方法可被覆写以在开发版本或测试中追加额外模块;Activity 的注入则在基类中自动完成。

工程结构与 Maven 配置

目录布局

examples/android-simple/ ├── AndroidManifest.xml(位于 src/main/) ├── pom.xml └── src/main/java/com/example/dagger/simple/ ├── AndroidModule.java // Android 专属依赖(Context、LocationManager) ├── DemoApplication.java // 自定义 Application,持有全局 ObjectGraph ├── DemoBaseActivity.java // 抽象基类,onCreate 中自动注入 ├── DemoModule.java // 业务模块占位,声明 injects 目标 ├── ForApplication.java // @Qualifier,区分 Application Context 与 Activity Context └── ui/HomeActivity.java // 具体页面,声明 @Inject 字段

依赖声明(pom.xml)

pom.xml 中,android-simple模块(artifactId)以com.squareup.dagger.example:dagger-example-parent为父工程,版本为1.2.6-SNAPSHOT,打包方式为apk。依赖上需要三类东西:

  • 运行时依赖com.squareup.dagger:dagger:提供ObjectGraph、@Module、@Provides等核心 API;
  • 编译期注解处理器com.squareup.dagger:dagger-compiler:标记为<optional>true</optional>,在编译阶段生成模块适配器(ModuleAdapter)等代码,运行时不需要携带;
  • Android SDKcom.google.android:android,scope 为provided,因为 android.jar 只在编译期使用,最终由设备/模拟器提供。

构建插件使用com.simpligility.maven.plugins:android-maven-plugin(<extensions>true</extensions>),负责将工程打包为 APK。Manifest 文件位于 src/main/AndroidManifest.xml,声明minSdkVersion=4、targetSdkVersion=17,Application 指定为.DemoApplication,启动 Activity 为.ui.HomeActivity。

核心一:自定义 Application 持有全局对象图

DemoApplication.java 是整个模式的枢纽:

public class DemoApplication extends Application { private ObjectGraph graph; @Override public void onCreate() { super.onCreate(); graph = ObjectGraph.create(getModules().toArray()); } protected List<Object> getModules() { return Arrays.asList( new AndroidModule(this), new DemoModule() ); } public void inject(Object object) { graph.inject(object); } }

三个要点:

  1. ObjectGraph.create(...)在onCreate中构建全局图:ObjectGraph是 dagger 1.x 的核心入口(源码见 core/src/main/java/dagger/ObjectGraph.java),负责把模块列表装配成一张可查询、可注入的依赖图。整个 App 生命周期内该图只创建一次。
  2. getModules()被设计为可覆写:这是本示例最关键的扩展点。生产环境下返回AndroidModule+DemoModule;在开发版或测试中,子类可覆写该方法追加TestModule之类的额外模块,从而在不改动主代码的前提下替换或补充依赖。
  3. 暴露inject(Object)门面方法:把graph.inject()包一层,供所有 Activity/Fragment 复用,避免业务代码直接接触ObjectGraph。

核心二:模块装配——@Module的两种语义

两个模块展示了@Module注解的两种典型配置:

AndroidModule:library = true的纯供给模块

AndroidModule.java 专门提供需要Context或Application才能创建的系统级依赖:

@Module(library = true) public class AndroidModule { private final DemoApplication application; public AndroidModule(DemoApplication application) { this.application = application; } @Provides @Singleton @ForApplication Context provideApplicationContext() { return application; } @Provides @Singleton LocationManager provideLocationManager() { return (LocationManager) application.getSystemService(LOCATION_SERVICE); } }
  • library = true:声明该模块只"提供"依赖、不"注入"对象,允许图中存在未使用的供给(不会因某个 provider 无人消费而报错)。这与complete = false配合,表示依赖关系可以由多个模块共同补全。
  • @Provides @Singleton:LocationManager这类系统服务在整个应用中应当是单例,因此同时标注@Singleton做作用域限定,保证每次注入拿到同一个实例。
  • @ForApplication限定符:这是示例里最有教学价值的细节。由于 Android 中Application和Activity都实现了Context,直接注入Context会产生歧义。ForApplication是一个用@Qualifier @Retention(RUNTIME)声明的自定义注解(见 ForApplication.java),配合@ForApplication Context的@Provides方法,显式区分"注入 Application Context"与"注入 Activity Context"两种语义——这正是 Dagger 限定符(Qualifier)机制在 Android 场景的经典用法。

DemoModule:complete = false的业务占位模块

DemoModule.java 是业务侧的入口:

@Module( injects = HomeActivity.class, complete = false ) public class DemoModule { // TODO put your application-specific providers here! }
  • injects = HomeActivity.class:显式声明本模块负责向哪些类执行注入。Dagger 编译期校验会据此确认注入目标的依赖是否齐备。
  • complete = false:表示该模块自身不是"完整的"依赖来源,允许依赖在其它模块(如AndroidModule)中提供。这也是示例刻意为之的松耦合设计——业务模块只负责声明注入入口,系统依赖交给平台模块。
  • 模块本体为空、仅留 TODO 注释,说明模块的职责主要是装配与声明,具体 provider 可以按需填充。

核心三:基类 Activity 自动注入

DemoBaseActivity.java 实现了"打开页面即注入完成"的效果:

public abstract class DemoBaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Perform injection so that when this call returns all dependencies will be available for use. ((DemoApplication) getApplication()).inject(this); } }

具体页面只需继承它并声明字段:

HomeActivity.java:

public class HomeActivity extends DemoBaseActivity { @Inject LocationManager locationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // After the super.onCreate call returns we are guaranteed our injections are available. // TODO do something with the injected dependencies here! } }

流程链路:HomeActivity启动 →super.onCreate→DemoBaseActivity从getApplication()拿到自定义DemoApplication→ 调用其inject(this)→ 触发ObjectGraph.inject按图解析并注入@Inject LocationManager。因此在super.onCreate返回之后,locationManager一定可用,这是示例在注释中反复强调的时序保证。

扩展视角:从"简单"到"子图"

示例在 Manifest 中仅声明了一个启动 Activity(src/main/AndroidManifest.xml),呈现的是"一个 Application 对应一张全局图"的最简形态。仓库中还提供了进阶版 android-activity-graphs,在该示例中每个 Activity 会基于全局图再创建子图(child graph),从而获得按 Activity 作用域注入、按页面粒度的单例、以及保持全局图干净等能力。其 README 同样注明该思想可推广到"用户会话(user session)"等自定义作用域——即根据业务生命周期动态创建专属对象图。这与本示例的getModules()可覆写设计一脉相承:模块列表的装配点(Application)越灵活,后续按作用域拆分图就越容易。

小结:可直接复用的落地清单

关注点实现位置关键语义
全局图生命周期DemoApplication.onCreate中ObjectGraph.create(...)全 App 仅创建一次
模块扩展点getModules()可覆写开发版/测试可追加模块
Android 专属依赖AndroidModule(library=true)提供 Context、系统服务
Context 歧义消除@ForApplication限定符区分 Application 与 Activity Context
注入入口声明DemoModule(injects+complete=false)业务模块只管声明与装配
自动注入DemoBaseActivity.onCreatesuper.onCreate返回后依赖即可用

按此结构,你可以在自己的 Android 工程中照搬四件事:① 自定义Application持有全局ObjectGraph;② 用可覆写的getModules()组装模块;③ 用基类 Activity 统一注入;④ 用@Qualifier解决多 Context 歧义。这也是该示例被保留在仓库中的价值所在——它用最小代码量讲清了 Dagger 在 Android 上的标准装配范式。

  • 依赖注入
  • 移动开发
  • 后端

【免费下载链接】dagger

A fast dependency injector for Android and Java.

项目地址:https://gitcode.com/gh_mirrors/dag/dagger
点击查看免费下载

相关推荐

上一篇:阿里开源Wan2.2-Animate-14B:消费级显卡实现电影级角色动画生成
下一篇:JUCE音频可视化硬件加速终极指南:如何利用GPU大幅提升渲染性能

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询