LiveData、Room、ViewModel(JAVA实现)

Posted by アライさん on 2019年10月22日

https://codelabs.developers.google.com/codelabs/android-room-with-a-view/index.html

Gradle配置

app的build.gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apply plugin: 'kotlin-kapt'
android {
// other configuration
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
}



// Room components
implementation "androidx.room:room-runtime:$rootProject.roomVersion"
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"

// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
kapt "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.androidxArchVersion"

// ViewModel Kotlin support
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.archLifecycleVersion"

// Coroutines
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

project的build.gradle:

1
2
3
4
5
6
ext {
roomVersion = '2.1.0-alpha07'
archLifecycleVersion = '2.2.0-alpha01'
androidxArchVersion = '2.0.0'
coroutines = '1.2.0'
}

## 数据实体:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Entity(tableName = "word_table")
public class Word {

@PrimaryKey
@NonNull
@ColumnInfo(name = "word")
private String mWord;

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

public String getWord(){return this.mWord;}
}

@Entity(tableName = "word_table")
public class Word {

@PrimaryKey(autoGenerate = true)
private int id;

@NonNull
private String word;

}

## Dao:
1
2
3
4
5
6
7
8
9
10
11
12
@Dao
public interface WordDao {
//@Insert(onConflict = OnConflictStrategy.REPLACE)是否处理主键重复时,替换
@Insert
void insert(Word word);

@Query("DELETE FROM word_table")
void deleteAll();

@Query("SELECT * from word_table ORDER BY word ASC")
LiveData<List<Word>> getAllWords();//如果不使用LiveData,直接用List
}

## RoomDatabase:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {

public abstract WordDao wordDao();

private static volatile WordRoomDatabase INSTANCE;

static WordRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (WordRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WordRoomDatabase.class, "word_database")
.addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
}

## Repository:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class WordRepository {

private WordDao mWordDao;
private LiveData<List<Word>> mAllWords;

WordRepository(Application application) {
WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
mWordDao = db.wordDao();
mAllWords = mWordDao.getAllWords();
}

LiveData<List<Word>> getAllWords() {
return mAllWords;
}


public void insert (Word word) {
new insertAsyncTask(mWordDao).execute(word);
}

private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {

private WordDao mAsyncTaskDao;

insertAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}

@Override
protected Void doInBackground(final Word... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
}

## ViewModel:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class WordViewModel extends AndroidViewModel {

private WordRepository mRepository;

private LiveData<List<Word>> mAllWords;

public WordViewModel (Application application) {
super(application);
mRepository = new WordRepository(application);
mAllWords = mRepository.getAllWords();
}

LiveData<List<Word>> getAllWords() { return mAllWords; }

public void insert(Word word) { mRepository.insert(word); }
}

## 获得联网数据,覆盖原数据库: 在RoomDatabase中调用: .addCallback(sRoomDatabaseCallback)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private static RoomDatabase.Callback sRoomDatabaseCallback =
new RoomDatabase.Callback(){

@Override
public void onOpen (@NonNull SupportSQLiteDatabase db){
super.onOpen(db);
new PopulateDbAsync(INSTANCE).execute();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {

private final WordDao mDao;

PopulateDbAsync(WordRoomDatabase db) {
mDao = db.wordDao();
}

@Override
protected Void doInBackground(final Void... params) {
mDao.deleteAll();
Word word = new Word("Hello");
mDao.insert(word);
word = new Word("World");
mDao.insert(word);
return null;
}
}

## 调用:
1
2
3
4
5
6
7
8
9
10
11
private WordViewModel mWordViewModel;
mWordViewModel = ViewModelProviders.of(this).get(WordViewModel.class);
mWordViewModel.getAllWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@Nullable final List<Word> words) {
// Update the cached copy of the words in the adapter.
adapter.setWords(words);
}
});
//增加
mWordViewModel.insert(word);