Dagger2/Hilt/Koin
Dagger是由square公司开发
https://github.com/square/dagger
Dagger2是dagger的升级版,现在由Google接手维护,
https://github.com/google/dagger
Hilt是在Dagger基础上进行二次封装构建的,相对Dagger来说,代码量更少,使用更简单。不同的是,Dagger利用注解使用APT去生成辅助代码,而Hilt是利用注解使用APT和ASM(字节码插桩)去生成辅助代码。https://dagger.dev/hilt/
Koin是轻量级的依赖注入框架,性能不及dagger2/Hilt,但是简单
https://github.com/InsertKoinIO/koin
好处:
举个具体的例子,一个容器里面装的是苹果,不用Dagger2的情况下我们应该这么写:
1 2 3 4
| public class Container{ Fruit f=new Apple(color,size); ... }
|
上面例子面临着一个问题,Container依赖了Apple实现,如果某一天需要修改Apple为Banana,那么你一定得改Container的代码。有没有一种方法可以不改Container呢?
可以使用Dagger2,我们可以把代码改成
1 2 3 4 5
| public class Container{ @Inject Fruit f; ... }
|
这样,Container的成员变量就自动初始化成Apple实例了,Container不用关心具体用哪个Fruit的实现,也不用关心到底用什么颜色多大的苹果。假如某一天要把苹果替换成香蕉,Container的代码是完全不需要改动的。
Dagger2简单使用
前提:注入方有构造函数可以@inject
@Inject:
a.在A类中标记B类字段,告诉dagger要把B类实例注入到A类中
b.在B类中标记构造方法,告诉dagger这是一个可以被注入的类,需要创建实例时,用标记的构造方法
@Component:
作为依赖方A和注入方B之间的桥梁。在Component中持有依赖方A的实例,当在A类中发现有被@Inject,会去查找B的构造方法,来创建B实例。
不需要构造函数
@Module和@Provides
implementation ‘com.google.dagger:dagger:2.35.1’
annotationProcessor ‘com.google.dagger:dagger-compiler:2.35.1’
implementation ‘com.google.dagger:dagger-android:2.35.1’
implementation ‘com.google.dagger:dagger-android-support:2.35.1’
annotationProcessor ‘com.google.dagger:dagger-android-processor:2.35.1’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class User { private String name = "stew NB"; public String getName(){ return name; } }
@Module public class UserModule { @Provides public User provideUser(){ return new User(); } }
@Component(modules = UserModule.class) public interface UserComponent { void inject(TestDagger2Activity activity); }
public class TestDagger2Activity extends AppCompatActivity {
@Inject User user;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dagger); DaggerUserComponent.create().inject(this); Log.d("TestDagger2Activity", "onCreate: " + user.getName()); } }
|
Hilt简单使用
@HiltAndroidApp
:所有使用hilt的应用都需要使用这个注解,被使用在Application类上
@AndroidEntryPoint
:Hilt可以为带有 @AndroidEntryPoint 注释的其他 Android 类提供依赖项,@AndroidEntryPoint
:可以被用在四大组件以及View上面
@Inject
:获取依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @HiltAndroidApp public class MyApplication extends Application {
public class HttpTool { }
@InstallIn(ApplicationComponent.class) @Module public class HttpModule { @Singleton @Provides public HttpTool getHttp(){ return new HttpTool(); } }
@AndroidEntryPoint public class TestHiltActivity extends AppCompatActivity {
@Inject HttpTool httpTool1;
@Inject HttpTool httpTool2;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hilt); Log.d("TestHiltActivity", "onCreate: "+httpTool1); Log.d("TestHiltActivity", "onCreate: "+httpTool2); } }
|
Koin简单使用
ext.koin_version = ‘2.2.0-rc-3’
// Koin for Kotlin
implementation “org.koin:koin-core:$koin_version”
implementation “org.koin:koin-core-ext:$koin_version”
// Koin for AndroidX
implementation “org.koin:koin-androidx-scope:$koin_version”
implementation “org.koin:koin-androidx-viewmodel:$koin_version”
implementation “org.koin:koin-androidx-fragment:$koin_version”
implementation “org.koin:koin-androidx-ext:$koin_version”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class MyApp:Application() {
private val modules = mutableListOf(homeModule)
override fun onCreate() { super.onCreate() ToastUtil.init(this) initKoin() }
private fun initKoin() { startKoin { androidLogger() androidContext(this@MyApp) modules(modules) } } }
val homeModule = module { single { RetrofitManager.getService(HomeApi::class.java) } single { HomeRepo(get()) } viewModel { HomeViewModel(get()) } }
class HomeFragment : BaseVMFragment<FragmentHomeBinding>() {
private val homeViewModel: HomeViewModel by viewModel() …….
}
class HomeViewModel(private val homeRepo: HomeRepo) : BaseViewModel() { …… }
class HomeRepo(private val homeApi: HomeApi) : BaseRepository() { …… }
|