android - 房间 Livedata.observeforever 在 Activity 恢复后无法正常工作

标签 android android-room android-architecture-lifecycle

我已经使用如下简单的 Room 测试代码测试了一些测试用例。 “dao.getAll().observeForever()”在主要 Activity 恢复后不起作用。 正确插入新词,但仅观察不起作用。 如果我使用 dao.getAll().observe(),它总是能正常工作。 不允许在 Activity 的 onCreate() 方法上使用 observeForever?

应用数据库.java

@Database(entities = {Word.class}, version = 2)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase sInstance;

public abstract WordDao wordDao();

public static AppDatabase getInstance(Context context) {
    if (sInstance == null) {
        synchronized (AppDatabase.class) {
            if (sInstance == null) {
                sInstance = Room.databaseBuilder(context.getApplicationContext(),
                        AppDatabase.class, "word.db").addMigrations(new Migration(1, 2) {
                    @Override
                    public void migrate(@NonNull SupportSQLiteDatabase database) {
                    }
                }).build();
            }
        }
    }

    return sInstance;
}

Word.java

@Entity
public class Word {
@PrimaryKey(autoGenerate = true)
public int uid;

public String word;

public Word(String word) {
    this.word = word;
}

WordDao.java

@Dao
public interface WordDao {
@Query("Select * from word")
LiveData<List<Word>> getAll();

@Update
void update(Word word);

@Insert
void insert(Word word);

主 Activity .java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = findViewById(R.id.textview);

    WordDao dao = AppDatabase.getInstance(this).wordDao();

    dao.getAll().observeForever(wordlist -> {
        StringBuilder builder = new StringBuilder();

        for (Word w : wordlist ) {
            builder.append(w.word).append(", ");
        }

        tv.setText(builder.toString());
    });

    findViewById(R.id.add).setOnClickListener(view -> new Thread(() -> {
        dao.insert(new Word("haha"));
    }).start());
}

构建.gradle

dependencies {
    def lifecycle_version = "1.1.1"
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
    testImplementation "android.arch.core:core-testing:$lifecycle_version"

    def room_version = "1.1.1"
    implementation "android.arch.persistence.room:runtime:$room_version"
    annotationProcessor "android.arch.persistence.room:compiler:$room_version"
    testImplementation "android.arch.persistence.room:testing:$room_version"
}

最佳答案

永远不要使用那样的架构组件。您应该使用 MVVM,因为它们旨在解决这个问题。模型应包含您关于哪个房间可以使用的数据。然后你的 View 应该只包含演示和对第三个组件 View 模型的引用。您的代码中缺少 ViewModel,它是这样的:

public class WordViewModel extends ViewModel {
    private MutableLiveData<List<Word>> mWords;
    private AppDatabase mDb;

    public WordViewModel(@NonNull Application application) {
        super(application);

        mWords = new MutableLiveData<List<Word>>();
        mDb = AppDatabase.getInstance(application.getApplicationContext());
    }

    public LiveData<List<User>> getWords() {
        loadWords();

        return words;
    }

    private void loadWords() {
       return mDb.wordDao().getAll();
    }
}

然后你的Activity会变成

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final TextView tv = findViewById(R.id.textview);

    WordViewModel viewModel = ViewModelProviders.of(this).get(WordViewModel.class);
    viewModel.getWords().observe(this, new Observer<List<Word>>() {
        @Override
        public void onChanged(@Nullable ResponseDataList resp) {
            StringBuilder builder = new StringBuilder();

            for (Word w : wordlist ) {
                builder.append(w.word).append(", ");
            }

            tv.setText(builder.toString());
        }
    });
}

如果评论中有任何不清楚的地方,请告诉我

关于android - 房间 Livedata.observeforever 在 Activity 恢复后无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51027275/

相关文章:

java - 安卓方法 : Method 1 returns empty String value with error and Method 2 returns a null pointer exceptions

android - Room 中 2 dao 的交易是真实的?

android - 使用 WorkManager 更新 Room 中的数据库条目

java - 安卓应用架构 : Implements user permission in lifecycle

android-architecture-components - 强制分页库数据源刷新

android - persist.img 在 android 中有什么用?

android - 为什么设置 setBackgroundColor 在我的自定义 listView 中不起作用

android - 关于辞职apk的建议

Java android room List in class无法弄清楚如何将此字段保存到数据库中

android - 我是否需要在其 onDestroy() 事件时调用 removeObserver 的生命周期?