Room and ViewModel of jetpack (III)


Source code analysis:ViewModel principle of jetpack


  1. Manage the data and manage the data in view separately
  2. Manage the saving and recovery of data, such as screen rotation, user clicking the back button, or switching languages
  3. It is very convenient to monitor the data changes on the UI
  4. It is mainly used in combination with livedata and room
    Note: ViewModel is only used to manage UI data. Never let it hold a reference to view, activity or fragment (beware of memory leakage).

ViewModel data recovery principle

public class NameViewModel extends ViewModel {
    public int i = 0;
    private MutableLiveData<String> currentName;
    public MutableLiveData<String> getCurrentName(){
            currentName=new MutableLiveData<>();
        return currentName;

Analysis entrance

1. Get ViewModel > >
//Get ViewModel
nameViewModel = ViewModelProviders.of(getActivity()).get(NameViewModel.class);

New version

nameViewModel = new ViewModelProvider.NewInstanceFactory().create(NameViewModel.class);


2 ViewModelProviders.of() >>

Saves the viewmodelstore and factory and returns the viewmodelprovider

Parameter 1: in getviewmodelstore() method
Get the viewmodelstore from the nonconfigurationinstances of the activity. If you can’t get it, just new

Parameter 2: generate ViewModel instance from reflection in factory

3 save and restore status > >

Onretainnonconfigurationinstance() is called automatically when saving the status and turning the screen
Getlastnonconfigurationinstance() restore state

4 save viewmodelstore > >

The activity quietly saves the viewmodelstore during the horizontal and vertical screen switching and puts it in the nonconfigurationinstances instance. When the horizontal and vertical screen switching is saved and restored, it is equivalent to that the ViewModel instance is always there, which avoids the data loss during the horizontal and vertical screen switching

Room usage

Table definition > >


1. @PrimaryKey

Primary key

Autogenerate = true self growth

2. @ColumnInfo


Name = “zcwfeng” field name

3. @Ignore

Indicates that an attribute is not added to the field of the generated table, but is only used temporarily

Definition of data access object

@Dao——Define Dao layer

public interface StudentDao {
1. @Query


@Query("select * from Student")
    List<Student> getAll();

Parameters can be added to query statements

//Query a record
    @Query("select * from Student where name like:name")
    Student findByName(String name);
    //Find records of partial ID numbers
    @Query("select * from Student where uid in (:userIds)")
    List<Student> getAllId(int[] userIds);
2. @Insert


    void insert(Student... students);
3. @Delete


    void delete(Student student);
4. @Update

to update

    void update(Student student);

Definition of Database > >


Define the tables contained in the database —– entities = {student. Class}
Database version number —— version = 1

@Database(entities = {Student.class},version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract StudentDao userDao();

Returns a subset of instances > >

public class NameTuple {
    public String firstName;

    public String lastName;

public interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    public List<NameTuple> loadFullName();

Physical relationships between tables > >

@Entity(foreignKeys = @ForeignKey(entity = User.class,
                                  parentColumns = "id",
                                  childColumns = "user_id"))
public class Book {
    public int bookId;

    public String title;

    @ColumnInfo(name = "user_id")
    public int userId;

Create nested objects > >

public class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;

public class User {
    public int id;

    public String firstName;

    public Address address;

Pass parameter set > >

public interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    public List<NameTuple> loadUsersFromRegions(List<String> regions);

Observable queries > >

public interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    public LiveData<List<User>> loadUsersFromRegionsSync(List<String> regions);
public interface MyDao {
   @Query("SELECT AS userName, AS petName "
          + "FROM user, pet "
          + "WHERE = pet.user_id")
   public LiveData<List<UserPet>> loadUserAndPetNames();

   // You can also define this class in a separate file, as long as you add the
   // "public" access modifier.
   static class UserPet {
       public String userName;
       public String petName;

Support rxjava > >

public interface MyDao {
    @Query("SELECT * from user where id = :id LIMIT 1")
    public Flowable<User> loadUserById(int id);

Return to cursor > >

public interface MyDao {
    @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5")
    public Cursor loadRawUsersOlderThan(int minAge);

Room database migration

Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");

static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE Book "
                + " ADD COLUMN pub_year INTEGER");

Jetpack (I) lifecycle and livedata
Lifecycle principles of jetpacks
Lifecycle livedata of jetpack

Databinding of jetpack (II)

Room and ViewModel of jetpack (III)
ViewModel principle of jetpack

Navigation of jetpack (IV)
Analysis of jetpack navigation principle

Paging Library of jetpack (V)

Workmanager of jetpack (VI)
Jetpack workmanager principles

Recommended Today

Tutorial on sending e-mail using net:: SMTP class in Ruby

Simple Mail Transfer Protocol(SMTP)SendE-mailAnd routing protocol processing between e-mail servers. RubyIt provides the connection of simple mail transfer protocol (SMTP) client of net:: SMTP class, and provides two new methods: new and start New takes two parameters: Server name defaults to localhost Port number defaults to 25 The start method takes these parameters: Server – […]