[英]Hilt - Java How to runtime inject String from Fragment to ViewModel constructor?
I have a String inside my Fragment that I'm trying to inject into the Fragment's ViewModel.我的片段中有一个字符串,我试图将其注入片段的 ViewModel。
I've been following this tutorial https://github.com/google/dagger/issues/2287我一直在关注本教程https://github.com/google/dagger/issues/2287
but I can't get the correct syntax from kotlin to java to work.但我无法从 kotlin 到 java 获得正确的语法来工作。
@AssistedFactory
public interface MainViewModelFactory {
MainViewModel create(String s);
}
@HiltViewModel
public class MainViewModel extends ViewModel {
private static final String TAG = "MainViewModel";
@Inject
public MainViewModel(@Assisted String testString) {
Log.d(TAG, "MainViewModel: Success injecting: " + testString);
}
@SuppressWarnings("unchecked")
public static ViewModelProvider.Factory provideFactory(
MainViewModelFactory assistedFactory,
String s
){
return new ViewModelProvider.Factory() {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) assistedFactory.create(s);
}
};
}
}
@Inject
MainViewModelFactory viewModelFactory;
private MainViewModel mainViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mainViewModel = new ViewModelProvider(this).get(MainViewModel.provideFactory(viewModelFactory, "Test string"));
//This line fails to even compile because I can't figure out how to fix my syntax from the kotlin to java conversion.
}
How can I correctly provide the ViewModel
from my factory method?如何从我的工厂方法中正确提供
ViewModel
?
When I try to compile it I get当我尝试编译它时,我得到
An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor.
on my factory class's method create
.在我的工厂类的方法
create
。
Edit:编辑:
I know you can use a module to provide the string, but I'm using it as a simple example before I try to get it working with injecting an object.我知道您可以使用模块来提供字符串,但在尝试让它与注入 object 一起工作之前,我将它用作一个简单的示例。
Using Hilt 2.37:使用刀柄 2.37:
implementation 'com.google.dagger:hilt-android:2.37'
annotationProcessor 'com.google.dagger:hilt-compiler:2.37'
First, You must add @Inject Annotation On Constructor Of Your Class首先,您必须在 Class 的构造函数上添加 @Inject 注释
Second, if your Constructor of your class has an argument or Object that is hard to Instantiate for dagger, You have to provide it from Module Class.其次,如果你的 class 的构造函数有一个参数或 Object 很难为匕首实例化,你必须从模块 Class 提供它。 for Example if your class use String Class or use an interface, abstract class that cannot be instantiate, you must provide an instance of that class in your Module Class.
for Example if your class use String Class or use an interface, abstract class that cannot be instantiate, you must provide an instance of that class in your Module Class.
In your ViewModel Class you can get it like repository class, because repository class is a simple class, dagger knows how to instantiate it, so there is no problem.在您的 ViewModel Class 中,您可以像存储库 class 一样获取它,因为存储库 class 是一个简单的 ZA2F2ED4F8EBC2CBB4C21A29DC40AB6
public class FragmentViewModel extends ViewModel {
private final RemoteRepository remoteRepository;
private final TestClass testClass;
@Inject
public CardInfoViewModel(RemoteRepository remoteRepository, TestClass testClass) { //How to inject object from Fragment into constructor?
this.remoteRepository = remoteRepository;
this.testClass = testClass;
}
}
module class模块 class
@InstallIn(Singletone.class)
@Module
public class ModuleClass {
@Singletone
@Provide
public TestClass provideTestClass() {
return new TestClass("Some Text");
}
}
Took two days to figure it out...but here's how to runtime inject (assisted injection) with hilt using Java.花了两天时间才弄明白...但这里是如何使用 Java 使用刀柄运行时注入(辅助注入)。
Requirements: Dagger 2.31+
要求:
Dagger 2.31+
Important notes:重要笔记:
DO NOT annotate your ViewModel with @HiltViewModel
or it will throw a compile time exception which did not help me identify the issue at all.不要使用
@HiltViewModel
注释您的 ViewModel,否则它会引发编译时异常,这根本无法帮助我识别问题。
ViewModel constructor should be annotated with @Inject instead of @AssistedInject.
[Hilt] Processing did not complete. See error above for details.
Full code with String
example:带
String
示例的完整代码:
@AssistedFactory
public interface MainViewModelFactory {
MainViewModel create(String s);
}
public class MainViewModel extends ViewModel {
private static final String TAG = "MainViewModel";
@AssistedInject
public MainViewModel(@Assisted String testString) {
Log.d(TAG, "MainViewModel: Success injecting: " + testString);
}
@SuppressWarnings("unchecked")
public static ViewModelProvider.Factory provideFactory(
MainViewModelFactory assistedFactory,
String s
){
return new ViewModelProvider.Factory() {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) assistedFactory.create(s);
}
};
}
}
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
@Inject
MainViewModelFactory viewModelFactory;
private MainViewModel mainViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mainViewModel = new ViewModelProvider(
this,
MainViewModel.provideFactory(viewModelFactory, "Test string")
).get(MainViewModel.class);
}
Took me a while to figure out there was a second param for ViewModelProvider
which needed the injected ViewModelFactory
to create the ViewModelProvider
我花了一段时间才发现
ViewModelProvider
的第二个参数需要注入的ViewModelFactory
来创建ViewModelProvider
Hopefully this answer helps people in the future.希望这个答案对未来的人们有所帮助。 I couldn't find any examples of how to do it.
我找不到任何如何做到这一点的例子。
Helpful answers:有用的答案:
https://github.com/google/dagger/issues/2287#issuecomment-761811164 https://github.com/google/dagger/issues/2287#issuecomment-761811164
Converting the kotlin way of creating the Java equivalent of ViewModelProviders
was quite confusing...转换 kotlin 方法来创建等同于
ViewModelProviders
的 Java 非常令人困惑......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.