【问题标题】:Android Room - Android Studio database inspector not showing DBAndroid Room - Android Studio 数据库检查器不显示数据库
【发布时间】:2021-05-12 14:21:52
【问题描述】:

我目前正在尝试学习 android,并正在使用数据库构建应用程序 - 我使用过 Room,但似乎无法让数据库检查器向我展示我的表格或确认它们存在!我有 4 个实体和 4 个 DAO。我没有遇到应用程序崩溃,我只是在数据库检查器中看不到我的数据库。在最终确定应用程序的所有 LiveData 和逻辑之前,我试图先通过检查器检查数据库,因为数据库是基础。

我已经构建了 android codelab,并交叉检查了我的 Room 架构与代码实验室。我已经下载并运行了相同的代码实验室,并且我能够检查它的数据库没问题。我已经使缓存失效并重新启动。

当我在主要活动onCreate() 中使用“ViewModelProvider”将主要活动链接到 ViewModel 时,它是否绕过了我的构造函数 - 它似乎不像我从构造函数中获取日志语句.. .

当我为 Room 重构任何东西时,我先构建 > 清理然后构建 > 重建。 我已经从主要活动(单个活动应用程序)> viewmodel > 存储库 > 数据库类添加了日志记录语句 - 并且正在返回所有日志,因此代码以正确的顺序调用。

当我尝试加载数据库检查器时,我看到以下内容; Android Studio Database Inspector View

这是 UI“向下”的代码 - 从主 Activity 开始;

public class MainActivity extends AppCompatActivity {

    private ViewModelTimerSetup viewModelTimerSetup;

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

        Log.d(ViewModelTimerSetup.getStaticLogTag(), "Main Activity - just before calling viewmodel");
        // generate a setupViewModel and therefore the db (vm > repository > db).
        viewModelTimerSetup = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory
                .getInstance(this.getApplication())).get(ViewModelTimerSetup.class);
        Log.d(ViewModelTimerSetup.getStaticLogTag(), "Main Activity - just after calling viewmodel");

视图模型;

public class ViewModelTimerSetup extends AndroidViewModel {
    public static String getStaticLogTag() {
        return STATIC_LOG_TAG;
    }
    private static final String STATIC_LOG_TAG = "my_logging";

    private final LiveData<List<TimerDesign>> allTimerDesigns;
    private final LiveData<List<TimerRecords>> allTimerRecords;

    // instantiate the app repository to access the database
    private AppRepository appRepository;

    /**
     * system required constructor, also gets the DBs from the app repository
     * @param application
     */
    public ViewModelTimerSetup(@NonNull Application application) {
        super(application);

        Log.d(STATIC_LOG_TAG, "Log tag - inside ViewModelTimerSetup constructor - pre making new db");
        // instantiate the access to the repository for db access
        appRepository = new AppRepository(application);
        Log.d(STATIC_LOG_TAG, "Log tag - inside the ViewModelTimerSetup constructor - after making new db");
        allTimerDesigns = appRepository.getAllTimerDesigns();
        allTimerRecords = appRepository.getAllTimerRecords();
    }

存储库构造器;

public AppRepository(Application application) {
        // find the db and if it doesnt exist, build one
        Log.d(ViewModelTimerSetup.getStaticLogTag(), "Repository - just before calling new database instance");
        AllTimersDatabase allTimersDatabase = AllTimersDatabase.getDatabase(application);
        Log.d(ViewModelTimerSetup.getStaticLogTag(), "Repository - just after calling new database instance");

        // instantiate all DAOs
        intervalDesignDAO = allTimersDatabase.intervalDesignDAO();
        intervalRecordsDAO = allTimersDatabase.intervalRecordsDAO();
        timerDesignDAO = allTimersDatabase.timerDesignDAO();
        timerRecordsDAO = allTimersDatabase.timerRecordsDAO();
      }

这里是数据库类(myDatabaseCallback 为简洁起见省略)。

@Database(entities = {TimerDesign.class, TimerRecords.class,
        IntervalDesign.class, IntervalRecord.class}, version = 1)
public abstract class AllTimersDatabase extends RoomDatabase {

    // generate a single instance of the full allTimersDatabase
    private static volatile AllTimersDatabase allTimersDatabaseInstance;

    // build an executor service with 4 threads for background queries
    private static final int NUMBER_OF_THREADS = 4;
    static final ExecutorService databaseWriteExecutor =
            Executors.newFixedThreadPool(NUMBER_OF_THREADS);

    // instantiate the DAOs
    public abstract IntervalDesignDAO intervalDesignDAO();
    public abstract IntervalRecordsDAO intervalRecordsDAO();
    public abstract TimerDesignDAO timerDesignDAO();
    public abstract TimerRecordsDAO timerRecordsDAO();

    /**
     * get one instance of the full db,
     * otherwise if no db exists, generate one
     * @param context
     * @return a full allTimersDatabase
     */
    public static AllTimersDatabase getDatabase(Context context) {
        if (allTimersDatabaseInstance == null) {
            synchronized (AllTimersDatabase.class) {
                if (allTimersDatabaseInstance == null) {
                    Log.d(ViewModelTimerSetup.getStaticLogTag(), "Database - before building new database instance");
                    allTimersDatabaseInstance = Room.databaseBuilder(context.getApplicationContext(),
                            AllTimersDatabase.class, "timers_database")
                            .fallbackToDestructiveMigration()
                            .addCallback(myDatabaseCallback)
                            .build();
                }
            }
        }

        Log.d(ViewModelTimerSetup.getStaticLogTag(), allTimersDatabaseInstance.toString());
        return allTimersDatabaseInstance;
    }

一个示例实体 - 所有实体都使用适当的 Room 注释、getter、setter 和 1 个构造函数构建

@Entity(tableName = "timer_design")
    public class TimerDesign {
    
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "timer_design_id")
        private int timerDesignID;
    
        @ColumnInfo(name = "timer_name")
        @NonNull
        private String timerName;
    
        @ColumnInfo(name = "total_duration", defaultValue = "00:00:00")
        @NonNull
        private String totalDuration;
    
        /**
         * constructor excl the id (id is autogenerated).
         * @param timerName
         */
        public TimerDesign(String timerName) {
            this.timerName = timerName;
            totalDuration = "00:00:00";
        }
    
        /**
         * setter for the ID
         * @param timerDesignID
         */
        public void setTimerDesignID(int timerDesignID) {
            this.timerDesignID = timerDesignID;
        }
    
        /**
         * getter for the id
         * @return
         */
        public int getTimerDesignID() {
            return timerDesignID;
        }
    
        /**
         * getter for the timer name
         * @return
         */
        public String getTimerName() {
            return timerName;
        }
    
        /**
         * setter for the timer name
         * @param timerName
         */
        public void setTimerName(@NonNull String timerName) {
            this.timerName = timerName;
        }
    
        /**
         * getter for the total duration
         * @return
         */
        @NonNull
        public String getTotalDuration() {
            return totalDuration;
        }
    
        /**
         * setter for the total duration
         * @param totalDuration
         */
        public void setTotalDuration(@NonNull String totalDuration) {
            this.totalDuration = totalDuration;
        }
    }

以及上述实体的 DAO;

@Dao
public interface TimerDesignDAO {

    // https://developer.android.com/reference/androidx/room/OnConflictStrategy.html
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    void insert(TimerDesign timerDesign);

    @Update
    void update(TimerDesign timerDesign);

    @Delete
    void delete(TimerDesign timerDesign);

    // delete all timers
    @Query("DELETE FROM timer_design")
    void deleteAllTimerDesigns();

    // get a list of all designed timers
    @Query("SELECT * FROM timer_design")
    LiveData<List<TimerDesign>> getAllTimerDesigns();

    // get a single timer design
    @Query("SELECT * FROM timer_design WHERE timer_design_id = :timerID")
    LiveData<List<TimerDesign>> getOneTimerDesign(int timerID);

    // get the id of the most recently inserted timer
    @Query("SELECT MAX(timer_design_id) FROM timer_design")
    int getMostRecentInsertedTimerID();
}

...最后我的 logcat 日志只显示“my_logging”键。沮丧中,我要求记录数据库实例的对象名称 .toString() 以查看是否正在创建对象。

2021-05-12 15:02:37.798 xxx D/my_logging: Main Activity - just before calling viewmodel
2021-05-12 15:02:37.799 xxx D/my_logging: Log tag - inside ViewModelTimerSetup constructor - pre making new db
2021-05-12 15:02:37.803 xxx D/my_logging: Repository - just before calling new database instance
2021-05-12 15:02:37.811 xxx D/my_logging: Database - before building new database instance
2021-05-12 15:02:37.841 xxx D/my_logging: xxx.AllTimersDatabase_Impl@cf67ddc
2021-05-12 15:02:37.841 xxx D/my_logging: Repository - just after calling new database instance
2021-05-12 15:02:37.862 xxx D/my_logging: Log tag - inside the ViewModelTimerSetup constructor - after making new db
2021-05-12 15:02:37.865 xxx D/my_logging: Main Activity - just after calling viewmodel
2021-05-12 15:02:38.349 xxx D/my_logging: Log tag - inside ViewModelTimerSetup constructor - pre making new db
2021-05-12 15:02:38.349 xxx D/my_logging: Repository - just before calling new database instance
2021-05-12 15:02:38.349 xxx D/my_logging: xxx.AllTimersDatabase_Impl@cf67ddc
2021-05-12 15:02:38.350 xxx D/my_logging: Repository - just after calling new database instance
2021-05-12 15:02:38.350 xxx D/my_logging: Log tag - inside the ViewModelTimerSetup constructor - after making new db

【问题讨论】:

  • 数据库里还有东西吗?对此不是 100% 确定的,但可能是在您实际添加某些内容之前不会创建数据库
  • 嗨 Ivan,我请求将一些对象添加到 RoomDatabase.Callback "myDatabaseCallback" 中的一些表中,但这对数据库检查器没有任何影响。与此同时,我将转到 UI 并查看构建完整 UI 后是否可以像用户一样添加对象,然后我不知道这是 Android Studio 问题还是数据库问题
  • 您总是可以尝试通过设备资源管理器查看数据库,它会在data/data/&lt;the_packagage&gt;/databases/ 中,您至少会期望timers_database 文件,也许还有文件 timers_database-wal 和 timers_database-shm 。如果这些存在,那么它与 Database Inspector 有关。您可以随时复制文件(全部 3 个)并使用 SQLite 工具查看它们。
  • 嗨 MikeT,好主意!我怎么没想到!是的,有一个timers_database 文件、一个timers_database_shm 和一个timers_database_wal。这三个人都有-rw-rw----的权限,我会按照建议复制它们并检查
  • 我认为您的设备至少是 android 8?这是检查员工作所必需的。

标签: android android-studio android-room


【解决方案1】:

我按照 @MikeT 在 cmets 中的建议从设备数据目录下载了 DB 文件。然后我加载到 DB Browser 中,发现所有 4 个表都按设计存在,还有几个显然是由 OS 和 Room 添加的。请求在初始数据库创建时添加的数据也存在(来自 myDatabaseCallback)。

我的 Android Studio 在过去几天升级到了 4.2.1,并且 DB 检查器正在正常运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2021-08-30
    • 2022-12-07
    • 1970-01-01
    相关资源
    最近更新 更多