【问题标题】:Android java, Dao interface in the database class seems to be weirdAndroid java,数据库类中的Dao接口似乎很奇怪
【发布时间】:2020-04-16 02:35:59
【问题描述】:

我最近在学习房间数据库,但这段代码似乎太奇怪了。 我试图理解这行代码,但也许我的谷歌搜索技能不是那么好。 你能解释一下吗?

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;
        }
    }

}

这是我的全部代码

【问题讨论】:

    标签: java android interface abstract-class android-room


    【解决方案1】:

    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)然后你得到:-

    查看 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多