JetPack——Hilt 手动依赖注入LoginRetrofitServicepublic class LoginRetrofitService { }UserRemoteDataSourcepublic class UserRemoteDataSource { private final LoginRetrofitService loginService; public UserRemoteDataSource(LoginRetrofitService loginService) { this.loginService loginService; } }UserLocalDataSourcepublic class UserLocalDataSource { }UserRepositorypublic class UserRepository { private final UserLocalDataSource localDataSource; private final UserRemoteDataSource remoteDataSource; public UserRepository(UserLocalDataSource localDataSource, UserRemoteDataSource remoteDataSource) { this.localDataSource localDataSource; this.remoteDataSource remoteDataSource; } }LoginViewModelFactorypublic class LoginViewModelFactory implements ViewModelProvider.Factory { private final UserRepository userRepository; public LoginViewModelFactory(UserRepository userRepository) { this.userRepository userRepository; } NonNull Override SuppressWarnings(unchecked) public T extends ViewModel T create(NonNull ClassT modelClass) { return (T) new LoginViewModel(userRepository); } }LoginViewModelpublic class LoginViewModel extends ViewModel { private final UserRepository userRepository; public LoginViewModel(UserRepository userRepository) { this.userRepository userRepository; } }ManualLoginActivity想要获取LoginViewModel需要根据依赖关系依次创建LoginRetrofitService、UserLocalDataSource、UserRemoteDataSource、UserRepository、LoginViewModelFactorypublic class ManualLoginActivity extends AppCompatActivity { private static final String TAG ManualLoginActivity.class.getSimpleName(); private LoginViewModel loginViewModel; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LoginRetrofitService loginService new LoginRetrofitService(); UserLocalDataSource localDataSource new UserLocalDataSource(); UserRemoteDataSource remoteDataSource new UserRemoteDataSource(loginService); UserRepository userRepository new UserRepository(localDataSource, remoteDataSource); LoginViewModelFactory factory new LoginViewModelFactory(userRepository); loginViewModel new ViewModelProvider(this, factory).get(LoginViewModel.class); String msg 【手动DI】依赖注入成功,ViewModel loginViewModel; Log.d(TAG, msg); showText(msg); } private void showText(String text) { TextView tv new TextView(this); tv.setText(text); tv.setGravity(Gravity.CENTER); tv.setTextColor(Color.BLACK); tv.setPadding(32, 200, 32, 32); setContentView(tv); } }Hilt实现依赖项注入可为您带来以下优势重用代码易于重构易于测试Hilt 是 Android 的依赖项注入库可减少在项目中执行手动依赖项注入的样板代码依赖libs.version.toml[versions] ...... ksp 2.0.20-1.0.24 hilt 2.57.1 [libraries] ...... hilt-android { group com.google.dagger, name hilt-android, version.ref hilt } hilt-compiler { group com.google.dagger, name hilt-compiler, version.ref hilt } [plugins] ...... ksp { id com.google.devtools.ksp, version.ref ksp } hilt { id com.google.dagger.hilt.android, version.ref hilt }build.gradle根目录plugins { ...... alias(libs.plugins.ksp) apply false alias(libs.plugins.hilt) apply false }build.gradle项目目录android { ...... compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget 17 } } plugins { ...... alias(libs.plugins.ksp) alias(libs.plugins.hilt) } dependencies { ...... implementation libs.hilt.android ksp libs.hilt.compiler }Hilt 依赖注入MyApplicationHiltAndroidApp public class MyApplication extends Application { private static MyApplication instance; Override public void onCreate() { super.onCreate(); instance this; } public static Context getContext() { return instance; } }LoginRetrofitServicepublic class LoginRetrofitService { Inject public LoginRetrofitService() { } }UserRemoteDataSourcepublic class UserRemoteDataSource { private final LoginRetrofitService loginService; Inject public UserRemoteDataSource(LoginRetrofitService loginService) { this.loginService loginService; } }UserLocalDataSourcepublic class UserLocalDataSource { Inject public UserLocalDataSource() { } }UserRepositorySingleton 全 App 共享一个Singleton public class UserRepository { private final UserLocalDataSource localDataSource; private final UserRemoteDataSource remoteDataSource; Inject public UserRepository(UserLocalDataSource localDataSource, UserRemoteDataSource remoteDataSource) { this.localDataSource localDataSource; this.remoteDataSource remoteDataSource; } }LoginViewModelHiltViewModel 构造函数 Inject → 依赖自动装配,不再需要手写 Factory。HiltViewModel public class LoginViewModel extends ViewModel { private final UserRepository userRepository; Inject public LoginViewModel(UserRepository userRepository) { this.userRepository userRepository; } }HiltLoginActivity为带有 AndroidEntryPoint 注解的其他 Android 类提供依赖项省去new的过程AndroidEntryPoint public class HiltLoginActivity extends AppCompatActivity { private static final String TAG HiltLoginActivity.class.getSimpleName(); private LoginViewModel loginViewModel; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 一行搞定:Hilt 已经把 UserRepository 及其下层依赖全部装配好 loginViewModel new ViewModelProvider(this).get(LoginViewModel.class); String msg 【Hilt】依赖注入成功,ViewModel loginViewModel; Log.d(TAG, msg); showText(msg); } private void showText(String text) { TextView tv new TextView(this); tv.setText(text); tv.setGravity(Gravity.CENTER); tv.setTextColor(Color.BLACK); tv.setPadding(32, 200, 32, 32); setContentView(tv); } }Module和InstallInModule 注解的类向 Hilt 提供有关如何创建无法通过构造函数注入提供的类型例如接口或第三方类的实例InstallIn 告知 Hilt 每个模块将用在或安装在哪个 Android 类中Bind 注入接口public interface DemoInterface { String demo(); }public class DemoImpl implements DemoInterface { Inject public DemoImpl() { } Override public String demo() { return DemoImpl; } }存在接口和具体实现创建一个带有 Binds 注解的抽象函数实现接口的依赖注入返回值为接口参数为实现Module InstallIn(SingletonComponent.class) public abstract class DemoModule { Binds public abstract DemoInterface bind(DemoImpl impl); }AndroidEntryPoint public class HiltModuleActivity extends AppCompatActivity { private static final String TAG HiltModuleActivity.class.getSimpleName(); Inject DemoInterface mDemo; // 业务用接口 Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout root new LinearLayout(this); root.setOrientation(LinearLayout.VERTICAL); root.setPadding(48, 200, 48, 48); TextView tv new TextView(this); tv.setGravity(Gravity.CENTER); tv.setTextColor(Color.BLACK); root.addView(tv); setContentView(root); String msg 当前实现: mDemo.demo(); Log.d(TAG, msg); tv.setText(msg); } }Provides 注入外部库Module InstallIn(SingletonComponent.class) public class DemoModule { Provides public Gson provideGson() { return new GsonBuilder().create(); } }AndroidEntryPoint public class HiltModuleActivity extends AppCompatActivity { Inject Gson gson; // Provides 提供的实例 Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv new TextView(this); tv.setText(Gson实例: gson.toJson(hello Provides)); setContentView(tv); } }Qualifier和RetentionQualifier 为同一类型定义多个绑定Retention 设置注解声明周期如下生成PrettyGson注解用于Gson实例对象的依赖注入Qualifier Retention(RetentionPolicy.RUNTIME) public interface PrettyGson { }Module InstallIn(SingletonComponent.class) public class DemoModule { // 默认绑定:压缩输出。 Provides public Gson provideGson() { return new GsonBuilder().create(); } // 同类型的第二个绑定,靠 PrettyGson 限定符区分,避免和上面的冲突。 Provides PrettyGson public Gson providePrettyGson() { return new GsonBuilder().setPrettyPrinting().create(); } }AndroidEntryPoint public class HiltModuleActivity extends AppCompatActivity { Inject Gson gson; // 默认绑定 Inject PrettyGson Gson prettyGson; // 限定符绑定 Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 用带字段的对象序列化,才能看出 setPrettyPrinting() 的换行缩进效果; // 序列化单个字符串没有结构,两种输出会一样。 MapString, String data new HashMap(); data.put(name, Kiro); data.put(action, Provides demo); String compact gson.toJson(data); String pretty prettyGson.toJson(data); TextView tv new TextView(this); tv.setText(默认Gson: compact \n\nPrettyGson:\n pretty); setContentView(tv); } }自带的预定义限定符如下注入ApplicationContext和ActivityContextInject ApplicationContext Context appContext; Inject ActivityContext Context activityContext;