朱颖 發表於 2026-1-10 09:19:34

Android Koin 注入入门指南

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>Android Koin 注入入门教程</li><ul class="second_class_ul"><li>一、什么是依赖注入(Dependency Injection)</li><ul class="third_class_ul"><li>1.1 不用 DI 会怎样?</li><li>问题</li><li>1.2 用 DI 后</li></ul><li>二、为什么选择 Koin?</li><ul class="third_class_ul"></ul><li>三、Koin 的三大核心概念</li><ul class="third_class_ul"><li>3.1 Module(模块)</li><li>3.2 Component(使用注入的地方)</li><li>3.3 Koin 容器</li></ul><li>四、最常用的注入方式(重点)</li><ul class="third_class_ul"><li>4.1single&mdash;&mdash; 单例(最常用)</li><li>4.2factory&mdash;&mdash; 每次新建</li><li>4.3singleOf&mdash;&mdash; 推荐写法 ⭐</li></ul><li>五、如何在 Android 中注入?</li><ul class="third_class_ul"><li>5.1 在 Activity / Fragment 中</li><li>5.2 在 ViewModel 中(推荐)</li><li>5.3 在普通类中(KoinComponent)</li></ul><li>六、接口 + 实现的标准写法</li><ul class="third_class_ul"></ul><li>七、Android 多模块项目中的 Koin</li><ul class="third_class_ul"><li>7.1 模块拆分示例</li></ul><li>八、新手必踩的 5 个坑(必看)</li><ul class="third_class_ul"><li>❌ 1️⃣ 忘了加模块</li><li>❌ 2️⃣ Listener 用了 factory</li><li>❌ 3️⃣single { MyClass }少了括号</li><li>❌ 4️⃣ Startup 顺序错误</li><li>❌ 5️⃣ 多进程没考虑</li></ul><li>九、一个完整可运行示例</li><ul class="third_class_ul"><li>AppModule.kt</li><li>Application.kt</li><li>使用</li></ul><li>十、总结(记住这 3 句话)</li><ul class="third_class_ul"></ul></ul></ul></div><p class="maodian"></p><h2>Android Koin 注入入门教程</h2>
<blockquote><p><strong>适合人群</strong></p>
<ul><li>Android 新手 / 刚接触 DI</li><li>从 Dagger/Hilt 转 Koin</li><li>多模块项目 / 车机项目开发者</li></ul>
<p><strong>目标</strong></p>
<ul><li>理解「为什么要用 Koin」</li><li>掌握 80% 常用注入方式</li><li>避免 80% 新手必踩坑</li></ul></blockquote>
<p class="maodian"></p><h3>一、什么是依赖注入(Dependency Injection)</h3>
<p class="maodian"></p><h4>1.1 不用 DI 会怎样?</h4>
<div class="jb51code"><pre class="brush:java;">class MusicViewModel {
    private val repository = MusicRepository()
}</pre></div>
<p class="maodian"></p><h4>问题</h4>
<ul><li>类<strong>强依赖</strong>具体实现</li><li>无法替换 / 无法测试</li><li>多模块会产生<strong>循环依赖</strong></li></ul>
<p class="maodian"></p><h4>1.2 用 DI 后</h4>
<div class="jb51code"><pre class="brush:java;">class MusicViewModel(
    private val repository: MusicRepository
)
</pre></div>
<ul><li>ViewModel <strong>只依赖接口</strong></li><li>具体实现由外部&ldquo;注入&rdquo;</li><li>解耦、可测试、可扩展</li></ul>
<p class="maodian"></p><h3>二、为什么选择 Koin?</h3>
<table><thead><tr><th>对比项</th><th>Koin</th><th>Dagger / Hilt</th></tr></thead><tbody><tr><td>学习成本</td><td>⭐ 低</td><td>高</td></tr><tr><td>编译速度</td><td>快</td><td>慢</td></tr><tr><td>写法</td><td>Kotlin DSL</td><td>注解 + 生成代码</td></tr><tr><td>多模块灵活性</td><td>高</td><td>中</td></tr><tr><td>车机项目</td><td>⭐ 非常合适</td><td>偏重</td></tr></tbody></table>
<blockquote><p><strong>一句话</strong>:<br />Koin = Kotlin 工程师友好的 DI 框架</p></blockquote>
<p class="maodian"></p><h3>三、Koin 的三大核心概念</h3>
<p class="maodian"></p><h4>3.1 Module(模块)</h4>
<blockquote><p><strong>告诉 Koin:如何创建对象</strong></p></blockquote>
<div class="jb51code"><pre class="brush:java;">val appModule = module {
    single { MusicRepository() }
}
</pre></div>
<p class="maodian"></p><h4>3.2 Component(使用注入的地方)</h4>
<div class="jb51code"><pre class="brush:java;">class MusicViewModel(
    private val repository: MusicRepository
)
</pre></div>
<p class="maodian"></p><h4>3.3 Koin 容器</h4>
<blockquote><p><strong>在 Application 中启动</strong></p></blockquote>
<div class="jb51code"><pre class="brush:java;">class MainApplication : Application() {
    override fun onCreate() {
      super.onCreate()
      startKoin {
            androidContext(this@MainApplication)
            modules(appModule)
      }
    }
}</pre></div>
<p class="maodian"></p><h3>四、最常用的注入方式(重点)</h3>
<p class="maodian"></p><h4>4.1single&mdash;&mdash; 单例(最常用)</h4>
<div class="jb51code"><pre class="brush:java;">single { MusicRepository() }</pre></div>
<ul><li>整个 App 只有一个实例</li><li>适合 Repository / Manager / Listener</li></ul>
<p class="maodian"></p><h4>4.2factory&mdash;&mdash; 每次新建</h4>
<div class="jb51code"><pre class="brush:java;">factory { PlayerController() }
</pre></div>
<ul><li>每次 inject 都创建新对象</li><li><strong>不适合 Listener</strong></li></ul>
<p class="maodian"></p><h4>4.3singleOf&mdash;&mdash; 推荐写法 ⭐</h4>
<div class="jb51code"><pre class="brush:java;">singleOf(::MusicRepository)
</pre></div>
<p>优势:</p>
<ul><li>自动解析构造函数参数</li><li>写法简洁</li><li>官方推荐</li></ul>
<p class="maodian"></p><h3>五、如何在 Android 中注入?</h3>
<p class="maodian"></p><h4>5.1 在 Activity / Fragment 中</h4>
<div class="jb51code"><pre class="brush:java;">class MainActivity : AppCompatActivity() {
    private val repository: MusicRepository by inject()
}</pre></div>
<p class="maodian"></p><h4>5.2 在 ViewModel 中(推荐)</h4>
<div class="jb51code"><pre class="brush:java;">class MusicViewModel(
    private val repository: MusicRepository
) : ViewModel()</pre></div>
<p>Module 中:</p>
<div class="jb51code"><pre class="brush:java;">viewModel {
    MusicViewModel(get())
}</pre></div>
<p class="maodian"></p><h4>5.3 在普通类中(KoinComponent)</h4>
<div class="jb51code"><pre class="brush:java;">class PlayerManager : KoinComponent {
    private val repository: MusicRepository by inject()
}</pre></div>
<p class="maodian"></p><h3>六、接口 + 实现的标准写法</h3>
<div class="jb51code"><pre class="brush:java;">interface MusicRepository
class MusicRepositoryImpl : MusicRepository</pre></div>
<p>Koin 配置:</p>
<div class="jb51code"><pre class="brush:java;">single&lt;MusicRepository&gt; {
    MusicRepositoryImpl()
}</pre></div>
<p>注入使用:</p>
<div class="jb51code"><pre class="brush:java;">private val repository: MusicRepository by inject()</pre></div>
<p class="maodian"></p><h3>七、Android 多模块项目中的 Koin</h3>
<p class="maodian"></p><h4>7.1 模块拆分示例</h4>
<div class="jb51code"><pre class="brush:java;">app
├── feature-localmusic
├── data
├── domain
└── base</pre></div>
<p>每个模块都有自己的 Koin module:</p>
<div class="jb51code"><pre class="brush:java;">val dataModule = module { ... }
val domainModule = module { ... }
</pre></div>
<p>在 Application 中统一加载:</p>
<div class="jb51code"><pre class="brush:java;">startKoin {
    modules(
      appModule,
      dataModule,
      domainModule
    )
}</pre></div>
<p class="maodian"></p><h3>八、新手必踩的 5 个坑(必看)</h3>
<p class="maodian"></p><h4>❌ 1️⃣ 忘了加模块</h4>
<div class="jb51code"><pre class="brush:java;">modules(appModule) // 少了 dataModule</pre></div>
<p>👉 直接导致 <code>NoDefinitionFoundException</code></p>
<p class="maodian"></p><h4>❌ 2️⃣ Listener 用了 factory</h4>
<div class="jb51code"><pre class="brush:java;">factory { PlayerStatusListener() } // 错</pre></div>
<p>👉 会被重复注册<br />✅ 应使用:</p>
<div class="jb51code"><pre class="brush:java;">single { PlayerStatusListener() }</pre></div>
<p class="maodian"></p><h4>❌ 3️⃣single { MyClass }少了括号</h4>
<div class="jb51code"><pre class="brush:java;">single { MyClass } // 错</pre></div>
<p>必须:</p>
<div class="jb51code"><pre class="brush:java;">single { MyClass() }
</pre></div>
<p class="maodian"></p><h4>❌ 4️⃣ Startup 顺序错误</h4>
<ul><li>inject 发生在 <code>startKoin</code> 之前</li><li>常见于 <code>androidx.startup</code></li></ul>
<p>👉 直接崩溃</p>
<p class="maodian"></p><h4>❌ 5️⃣ 多进程没考虑</h4>
<ul><li>车机项目常见</li><li>每个进程都会启动 Koin</li></ul>
<p>👉 单例 &ne; 全局唯一</p>
<p class="maodian"></p><h3>九、一个完整可运行示例</h3>
<p class="maodian"></p><h4>AppModule.kt</h4>
<div class="jb51code"><pre class="brush:java;">val appModule = module {
    singleOf(::MusicRepository)
    viewModel { MusicViewModel(get()) }
}</pre></div>
<p class="maodian"></p><h4>Application.kt</h4>
<div class="jb51code"><pre class="brush:java;">class MainApplication : Application() {
    override fun onCreate() {
      super.onCreate()
      startKoin {
            androidContext(this@MainApplication)
            modules(appModule)
      }
    }
}</pre></div>
<p class="maodian"></p><h4>使用</h4>
<div class="jb51code"><pre class="brush:java;">class MusicFragment : Fragment() {
    private val viewModel: MusicViewModel by viewModel()
}</pre></div>
<p class="maodian"></p><h3>十、总结(记住这 3 句话)</h3>
<p>1️⃣ <strong>Koin 不是魔法,只是对象工厂</strong><br />2️⃣ <strong>single / factory 决定的是生命周期</strong><br />3️⃣ <strong>Listener / Manager 一定要 single</strong></p>
<p>到此这篇关于Android Koin 注入入门教程的文章就介绍到这了,更多相关Android Koin 注入内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Android Koin2基本使用的那件事儿</li><li>Android依赖注入框架Dagger2的使用方法</li><li>Android ButterKnife依赖注入框架使用教程</li><li>Android&nbsp;Hilt依赖注入的使用讲解</li><li>Android中WebView无法后退和js注入漏洞的解决方案</li><li>Android中三种注入事件方法比较</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Android Koin 注入入门指南