首页 > 解决方案 > ViewModel onChanged() 被无限调用

问题描述

我计算当回收库中的复选框检查或未选中时。它工作正常,但是当我向 recyclerView 添加新项目时,有时会无限调用 onChanged() 并且 UI 冻结。

在 MainActivity

    @Override
public void onCheckBoxCheckListener(final TaskEntry taskEntry, final boolean isChecked) {

    AppExecutors.getInstance().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            taskEntry.setChecked(isChecked);
            mDb.taskDao().updateTask(taskEntry);

        }
    });

}

private void setupViewModel() {
    MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);
    viewModel.getTasks().observe(this, new Observer<List<TaskEntry>>() {
        @Override
        public void onChanged(List<TaskEntry> taskEntries) { 

            calculatePercent(taskEntries);
            mprogressBar.setProgress((int)mTotalProgressPercent);
            mProgressValue.setText((int)mTotalProgressPercent + " %");

            //this gets logged infinity when a new item is added
            Log.d("setupVM", " called TotalPercent = " + (int)mTotalProgressPercent );

            mAdapter.setTasks(taskEntries);
        }
    });
}

private void calculatePercent(List<TaskEntry> taskEntries) {
    int countChecked = 0;
    for(TaskEntry i: taskEntries){
        if(i.isChecked()) countChecked++;
    }
    mTotalProgressPercent = (double)countChecked/taskEntries.size() *100;
}

主视图模型

public class MainViewModel extends AndroidViewModel {

private LiveData<List<TaskEntry>> tasks;

public MainViewModel(@NonNull Application application){
    super(application);
    AppDatabase database = AppDatabase.getInstance(this.getApplication());
    tasks = database.taskDao().loadAllTasks();
}

public LiveData<List<TaskEntry>> getTasks() {
    return tasks;
}

当使用另一个活动添加新项目(任务)时,使用 onSaveButtonclicked 方法

 public void onSaveButtonClicked() {
    String description = mEditText.getText().toString();
    int priority = getPriorityFromViews();
    Date date = new Date();

    final TaskEntry taskEntry = new TaskEntry(description, priority, date, false );

    AppExecutors.getInstance().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            if(mTaskId == DEFAULT_TASK_ID){
                mDb.taskDao().insertTask(taskEntry);
            }else {
                taskEntry.setId(mTaskId);  //for updating any task, works fine
                mDb.taskDao().updateTask(taskEntry);
            }
            finish(); // return to main activity
        }
    });
}

标签: androidviewmodelandroid-livedataobserver-patternandroid-mvvm

解决方案


我解决了这个问题。我只是在 Checkbox 上使用了 onClickListener 而不是 OnCheckedChangeListener。OnCheckedChanged() 在循环中被一次又一次地调用。但现在它可以与 onClickListener 一起正常工作。


推荐阅读