英文:
How to use the androidx.lifecycle.ViewModelProvider in Java
问题
我最近在学习关于架构组件的内容,正在按照旧教程使用旧方法进行操作:
mainActivityViewModel =
new ViewModelProvider(this).get(MainActivityViewModel.class);
但在ViewModelProvider的文档中,唯一可用的构造函数是:
ViewModelProvider(ViewModelStoreOwner, Factory) 和 ViewModelProvider(ViewModelStore, Factory)。
所以我尝试了以下方法,但不确定在重写的方法中应该返回什么,它目前返回null,导致程序崩溃。
public class MainActivity extends AppCompatActivity {
private NoteViewModel noteViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
noteViewModel = new ViewModelProvider(this, new ViewModelProvider.Factory() {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return null;
}
}).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<NoteEntity>>() {
@Override
public void onChanged(List<NoteEntity> noteEntities) {
Toast.makeText(MainActivity.this,"Changed",Toast.LENGTH_LONG).show();
}
});
}
}
我的方法是否正确?我现在完全迷失了。我应该从重写的方法中返回什么?
英文:
I'm recently learning about the architectural components and was following the old tutorial where they used the old method:
<!-- language-all: java -->
mainActivityViewModel =
new ViewModelProvider(this).get(MainActivityViewModel.class);
But in the documentation for the ViewModelProvider, the only constructors available are
ViewModelProvider(ViewModelStoreOwner, Factory)
&
ViewModelProvider(ViewModelStore, Factory)
.
So I did something like this but I'm not sure what to do in the overridden method and it currently returns null that crashes the program.
public class MainActivity extends AppCompatActivity {
private NoteViewModel noteViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
noteViewModel = new ViewModelProvider(this, new ViewModelProvider.Factory() {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return null;
}
}).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<NoteEntity>>() {
@Override
public void onChanged(List<NoteEntity> noteEntities) {
Toast.makeText(MainActivity.this,"Changed",Toast.LENGTH_LONG).show();
}
});
}
}
Is my approach correct? I'm absolutely lost right now. What am I supposed to return from the overridden method?
答案1
得分: 2
noteViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(NoteViewModel.class);
当我们在 ViewModel 的构造函数中传递参数时(除了 Application 参数),我们使用自定义的工厂。
在 Gradle 依赖中添加以下代码:
def lifecycle_version = "2.2.0"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
//
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
英文:
Use this
noteViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(NoteViewModel.class;
We use custom factory, when we pass param to the constructor of ViewModel (apart from Application param).
and gradle dependency in case,
def lifecycle_version = "2.2.0"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
//
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
答案2
得分: 1
首先,您需要在活动类中初始化 ViewModel,如下所示:
noteViewModel = ViewModelProvider(this).get(NoteViewModel.class);
在 NoteViewModel.java
中:
您需要为存储模型提供的更新数据定义 LiveData 变量,并将其更新传递到 ViewModel。
public class NoteViewModel extends AndroidViewModel {
AppRepository appRepository;
MediatorLiveData<List<NoteEntity>> mediatorData;
public NoteViewModel (@NonNull Application application) {
super(application);
mediatorData = new MediatorLiveData<>();
appRepository = new AppRepository(MyApplication.apiService, application.retrofit);
}
public MediatorLiveData<List<NoteEntity>> getMediatorLiveData() {
return mediatorData;
}
public void getNoteEntry() {
try {
mediatorData.addSource(appRepository.getNoteEntry(), new Observer<List<NoteEntity>>() {
@Override
public void onChanged(@Nullable List<NoteEntity> data) {
mediatorData.postValue(data);
}
});
} catch (Exception e) {
}
}
}
在 MainActivity
的 onCreate()
方法中,注册观察者并从 ViewModel 调用 API:
noteViewModel.getMediatorLiveData().observe(this, new Observer<List<NoteEntity>>() {
@Override
public void onChanged(List<NoteEntity> noteEntities) {
Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_LONG).show();
}
});
noteViewModel.getNoteEntry();
AppRepository.java
文件如下:
class AppRepository() {
ApiService apiService;
Retrofit retrofit;
public AppRepository(ApiService apiService, Retrofit retrofit) {
this.apiService = apiService;
this.retrofit = retrofit;
}
public MediatorLiveData<List<NoteEntity>> getNotes() {
MediatorLiveData<List<NoteEntity>> data = new MediatorLiveData<List<NoteEntity>>();
apiService.getNotes().enqueue(new Callback<List<NoteEntity>>() {
@Override
void onResponse(Call<List<NoteEntity>> call, Response<List<NoteEntity>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
data.postValue(response.body()); //成功数据
} else {
data.postValue(null); //错误
}
} else {
data.postValue(null); //错误
}
}
@Override
void onFailure(Call<List<NoteEntity>> call, Throwable t) {
data.postValue(null); //错误
}
});
return data;
}
}
英文:
First you need to initialize viewmodel in activity class like :
noteViewModel = ViewModelProvider(this).get(NoteViewModel.class);
In NoteViewModel.java
You need to define livedata variable for storing updated data provided by model and update post to view model
NoteViewModel.java file look like :
public class NoteViewModel extends AndroidViewModel {
AppRepository appRepository;
MediatorLiveData<List<NoteEntity>> mediatorData;
public NoteViewModel (@NonNull Application application) {
super(application);
mediatorData=new MediatorLiveData<>();
appRepository=new AppRepository((MyApplication).apiService, application.retrofit);
}
public MediatorLiveData<List<NoteEntity>> getMediatorLiveData() {
return mediatorVideoData;
}
public void getNoteEntry()
{
try {
mediatorData.addSource(appRepository.getNoteEntry(), new Observer<List<NoteEntity>>() {
@Override
public void onChanged(@Nullable List<NoteEntity> data) {
mediatorData.postValue(data);
}
});
}catch (Exception e)
{
}
}
}
In onCreate()
of Mainactivity
register observer like and call the API from view model like
noteViewModel.getMediatorLiveData().observe(this, new Observer<List<NoteEntity>>() {
@Override
public void onChanged(List<NoteEntity> noteEntities) {
Toast.makeText(MainActivity.this,"Changed",Toast.LENGTH_LONG).show();
}
});
noteViewModel.getNoteEntry();
AppRepository.java file look like
class AppRepository() {
ApiService apiService;
Retrofit retrofit;
public AppRepository(ApiService apiService ,Retrofit retrofit){
this.apiService = apiService;
this.retrofit = retrofit;
}
public MediatorLiveData<List<NoteEntity>> getNotes() {
MediatorLiveData<List<NoteEntity>> data = new MediatorLiveData<List<NoteEntity>>()
apiService.getNotes()
.enqueue(new Callback<List<NoteEntity>> {
@Override
void onResponse(
Call<List<NoteEntity>> call,
Response<List<NoteEntity>> response
) {
if (response.isSuccessful()) {
if(response.body()!=null){
data.postValue(response.body()); //successfull data
}else{
data.postValue(null); //error
}
} else {
data.postValue(null); //error
}
}
@Override
fun onFailure(
Call<List<NoteEntity>> call,
Throwable t
) {
data.postValue(null); //error
}
})
return data;
}
}
答案3
得分: 1
Kotlin 代码。
在 build.gradle 中添加
implementation "androidx.activity:activity-ktx:1.1.0"
然后
val noteViewModel by viewModels<NoteViewModel>()
英文:
Kotlin Code.
In build.gradle add
implementation "androidx.activity:activity-ktx:1.1.0"
then
val noteViewModel by viewModels<NoteViewModel>()
答案4
得分: 0
找到了解决方法,经过4个小时的研究。
noteViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(NoteViewModel.class);
另外,这些依赖项应该添加到 gradle 文件中。
def room_version = "2.2.5";
def lifecycle_version = "2.2.0";
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
不确定错误是否是因为我漏掉了注解依赖,但现在一切都正常工作了。
英文:
Figured it out after 4 hours.
noteViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(NoteViewModel.class);
Also these dependencies should be added to the gradle file.
def room_version = "2.2.5"
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
Not sure if the error was caused because I missed the annotation dependency. But everything works now.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论