我最近正在学习Room Database,但是这段代码似乎太奇怪了。
我试图理解这行代码,但也许我的Google搜索技能不是那么好。
你能解释一下吗?

public abstract NoDoDao noDoDao();


我不明白的是,这里的接口叫“ NoDoDa”,怎么能称呼它为“方法”或“功能”呢?这是我第一次看到这种语法。为什么还有“抽象关键字”?

package com.paige.room.data;

import android.content.Context;
import android.os.AsyncTask;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.paige.room.model.NoDo;

@Database(entities = {NoDo.class}, version = 1)
public abstract class NoDoRoomDatabase extends RoomDatabase {

    //Don't want to create a lot of instances, singleton
    //volatile means "don't store in the cache"
    private static volatile NoDoRoomDatabase INSTANCE;
    public abstract NoDoDao noDoDao();

    public static NoDoRoomDatabase getDatabase(final Context context){
        if(INSTANCE == null){
            //synchronized keyword, for UI Thread, force it to work as it is supposed to do
            synchronized (NoDoRoomDatabase.class){
                if(INSTANCE == null){
                    //create our db
                    INSTANCE = Room.databaseBuilder(
                            context,
                            NoDoRoomDatabase.class,
                            "nodo_database")
                            .addCallback(roomDatabaseCallBack)
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    //callback
    private static RoomDatabase.Callback roomDatabaseCallBack =
            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 NoDoDao noDoDao;

        PopulateDBAsync(NoDoRoomDatabase db) {
            this.noDoDao = db.noDoDao();
        }

        @Override
        protected Void doInBackground(Void... voids) {
//            noDoDao.deleteAll(); //removes all items from our table
//            //for testing
//            NoDo noDo = new NoDo("Buy a new Ferrari");
//            noDoDao.insert(noDo);
//
//            noDo = new NoDo("Buy a Big House");
//            noDoDao.insert(noDo);

            return null;
        }
    }

}



这是我的整个代码

最佳答案

NoDoDao是一个abstract类,无法实例化(构造),但可以使用该类。这是怎么回事。

您可能没有意识到,Room会生成代码,而正是这些抽象使底层代码可以代表您实现。

假设您的实体类别NoDO是:-

@Entity
public class NoDo {

    @PrimaryKey
    Long id;
}


而您的Dao类NoDoDao是:-

@Dao
public abstract class NoDoDao {

    @Query("SELECT * FROM nodo")
    abstract List<NoDo> getnothing();
}


然后编译(F9),然后得到:

java - Android java,数据库类中的Dao接口(interface)似乎很奇怪-LMLPHP

查看NoDoDao_Impl,您会得到:-

public final class NoDoDao_Impl extends NoDoDao {
  private final RoomDatabase __db;

  public NoDoDao_Impl(RoomDatabase __db) {
    this.__db = __db;
  }

  @Override
  List<NoDo> getnothing() {
    final String _sql = "SELECT * FROM nodo";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
      final List<NoDo> _result = new ArrayList<NoDo>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final NoDo _item;
        _item = new NoDo();
        if (_cursor.isNull(_cursorIndexOfId)) {
          _item.id = null;
        } else {
          _item.id = _cursor.getLong(_cursorIndexOfId);
        }
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }
}


注释处理器已经生成了真正的getNothing代码。

重要的是NoDoRoomDatabase_Impl为:-

public final class NoDoRoomDatabase_Impl extends NoDoRoomDatabase {
  private volatile NoDoDao _noDoDao;

  @Override
  protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
    final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate(1) {
      @Override
      public void createAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("CREATE TABLE IF NOT EXISTS `NoDo` (`id` INTEGER, PRIMARY KEY(`id`))");
        _db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
        _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1fdde93d9c60610ae88bf0c74771844a')");
      }

      @Override
      public void dropAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("DROP TABLE IF EXISTS `NoDo`");
        if (mCallbacks != null) {
          for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
            mCallbacks.get(_i).onDestructiveMigration(_db);
          }
        }
      }

      @Override
      protected void onCreate(SupportSQLiteDatabase _db) {
        if (mCallbacks != null) {
          for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
            mCallbacks.get(_i).onCreate(_db);
          }
        }
      }

      @Override
      public void onOpen(SupportSQLiteDatabase _db) {
        mDatabase = _db;
        internalInitInvalidationTracker(_db);
        if (mCallbacks != null) {
          for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
            mCallbacks.get(_i).onOpen(_db);
          }
        }
      }

      @Override
      public void onPreMigrate(SupportSQLiteDatabase _db) {
        DBUtil.dropFtsSyncTriggers(_db);
      }

      @Override
      public void onPostMigrate(SupportSQLiteDatabase _db) {
      }

      @Override
      protected RoomOpenHelper.ValidationResult onValidateSchema(SupportSQLiteDatabase _db) {
        final HashMap<String, TableInfo.Column> _columnsNoDo = new HashMap<String, TableInfo.Column>(1);
        _columnsNoDo.put("id", new TableInfo.Column("id", "INTEGER", false, 1, null, TableInfo.CREATED_FROM_ENTITY));
        final HashSet<TableInfo.ForeignKey> _foreignKeysNoDo = new HashSet<TableInfo.ForeignKey>(0);
        final HashSet<TableInfo.Index> _indicesNoDo = new HashSet<TableInfo.Index>(0);
        final TableInfo _infoNoDo = new TableInfo("NoDo", _columnsNoDo, _foreignKeysNoDo, _indicesNoDo);
        final TableInfo _existingNoDo = TableInfo.read(_db, "NoDo");
        if (! _infoNoDo.equals(_existingNoDo)) {
          return new RoomOpenHelper.ValidationResult(false, "NoDo(a.so59478461.NoDo).\n"
                  + " Expected:\n" + _infoNoDo + "\n"
                  + " Found:\n" + _existingNoDo);
        }
        return new RoomOpenHelper.ValidationResult(true, null);
      }
    }, "1fdde93d9c60610ae88bf0c74771844a", "1d145662ebde2538a8da3217996c0550");
    final SupportSQLiteOpenHelper.Configuration _sqliteConfig = SupportSQLiteOpenHelper.Configuration.builder(configuration.context)
        .name(configuration.name)
        .callback(_openCallback)
        .build();
    final SupportSQLiteOpenHelper _helper = configuration.sqliteOpenHelperFactory.create(_sqliteConfig);
    return _helper;
  }

  @Override
  protected InvalidationTracker createInvalidationTracker() {
    final HashMap<String, String> _shadowTablesMap = new HashMap<String, String>(0);
    HashMap<String, Set<String>> _viewTables = new HashMap<String, Set<String>>(0);
    return new InvalidationTracker(this, _shadowTablesMap, _viewTables, "NoDo");
  }

  @Override
  public void clearAllTables() {
    super.assertNotMainThread();
    final SupportSQLiteDatabase _db = super.getOpenHelper().getWritableDatabase();
    try {
      super.beginTransaction();
      _db.execSQL("DELETE FROM `NoDo`");
      super.setTransactionSuccessful();
    } finally {
      super.endTransaction();
      _db.query("PRAGMA wal_checkpoint(FULL)").close();
      if (!_db.inTransaction()) {
        _db.execSQL("VACUUM");
      }
    }
  }

  @Override
  public NoDoDao noDoDao() {
    if (_noDoDao != null) {
      return _noDoDao;
    } else {
      synchronized(this) {
        if(_noDoDao == null) {
          _noDoDao = new NoDoDao_Impl(this);
        }
        return _noDoDao;
      }
    }
  }
}


查看如何将NoDoDao基本上重写为NoDoDao_Impl

10-08 03:54