【发布时间】:2021-12-03 16:49:58
【问题描述】:
问题:我收到null 数据库名称错误。我的MainActiity.class 中的 Android Room 数据库调用继续执行,尽管提示让用户选择数据库名称。
我正在尝试做的事情:我还在学习Android,但我正在尝试在一个单独的应用程序中锻炼,使用大师Room数据库来管理使用应用程序使用的多个Room 数据库(这是一个沙盒类型的应用程序来发挥这个想法)。这个数据库管理功能运行良好,但事情是硬编码的。因此,我正处于希望用户能够通过使用sharedPreferences 和自定义alert 提示的步骤中,可以选择在安装第一个房间数据库时创建命名并在其后添加其他人。稍后添加它们的选项不是问题,因为将加载某些内容。但是,在初始应用程序启动时,我希望用户可以选择创建和命名第一个数据库,而不是创建默认数据库——这并不是什么大不了的事,但为什么用户有一个潜在的默认数据库从不使用。我什至可以开发一种重命名方法,我会这样做,但允许用户这样做似乎是有意义的。
我尝试过的:我尝试创建一些方法来封装和分离 DB 调用与提示,但代码仍然吹到 DB 代码。我对延迟Room 进行了一些搜索,但找不到任何特定的内容。我愿意接受他人的智慧。
编写代码,这只是一项活动,因为我在玩这个想法......并同时学习。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "DB_INFO";
SharedPreferences sharedPreferences;
SharedPreferences.Editor settings;
String databaseName;
String prevDB;
Button button;
MasterDatabase masterDB;
List<MasterDatabaseList> mdbList;
ArrayList<BaseDatabase> bdbList = new ArrayList<>();
// Current Database
int currentBaseDBIndex = -1;
BaseDatabase currentDB = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
sharedPreferences = getSharedPreferences("AppSettings", MODE_PRIVATE);
settings = sharedPreferences.edit();
setupOnClickActions();
startChecks();
Toast.makeText(this, "database: " + databaseName + "\r\n" + "prevDB: " + prevDB, Toast.LENGTH_LONG).show();
}
private void startChecks(){
if(isFirstTime()) {
databaseName = PopupDialog.AlertInputBox(this, "Enter Research Project Name",
"Without spaces or special characters, enter a name for your research project.");
settings.putString("database", databaseName);
settings.commit();
settings.apply();
startDBs();
}else{
databaseName = PopupDialog.AlertInputBox(this, "Enter Research Project Name",
"Without spaces or special characters, enter a new or existing name for your research project.");
settings.putString("prevDB", sharedPreferences.getString("database", ""));
settings.putString("database", databaseName);
settings.commit();
settings.apply();
prevDB = sharedPreferences.getString("prevDB", "");
startDBs();
}
}
private void startDBs(){
masterDB = MasterDatabase.getInstance(this);
mdbList = masterDB.getMasterDao().getAllDatabases();
// Add a DB if none exists
if(mdbList.size()<1){
addBaseDB("sample.db");
}
setCurrentIndexDBandDao(databaseName); /* Add some data to db1 IF it exists (it should) --------------------- */
if (currentBaseDBIndex > -1 && currentDB.getBaseDao().count() < 1) {
currentDB.getBaseDao().insert(new BaseTable("Added " + databaseName + " ... etc."));
}
/* Extract and Log Data for ALL the BaseDatabase databases i.e. db1 and db2 */
for(MasterDatabaseList masterdb: masterDB.getMasterDao().getAllDatabases()) {
Log.d(TAG,"Database is " + masterdb.getDatabaseName());
setCurrentIndexDBandDao(masterdb.getDatabaseName());
if (currentBaseDBIndex > -1) {
for(BaseTable bt: currentDB.getBaseDao().getAllBaseTables()) {
Log.d(TAG,"Extracted Base Table row where MyData is" + bt.getMydata());
}
}
}
}
// METHODS =========================================================================================================
// Attempt to clear and reset SharedPreferences to a user first execution
private void setupOnClickActions(){
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
settings.putBoolean("firstTime", false);
settings.clear();
settings.commit();
settings.apply();
}
});
}
/* Add a new Database
Note that it assumes that it will now be the current
so the current values are set */
private void addBaseDB(String baseDBName) {
masterDB.getMasterDao().insert(new MasterDatabaseList(baseDBName));
}
/* Build/ReBuild the 3 Lists according to the master database*/
private void buildBaseLists() {
bdbList.clear();
mdbList = masterDB.getMasterDao().getAllDatabases();
// Loop through the databases defined in the master database adding the database and dao to the respective lists
for (MasterDatabaseList masterDB: masterDB.getMasterDao().getAllDatabases()) {
BaseDatabase baseDB = BaseDatabase.getInstance(this, masterDB.getDatabaseName());
bdbList.add(baseDB);
}
}
/* Set the currentDB according to the database name*/
private void setCurrentIndexDBandDao(String baseDBName) {
currentBaseDBIndex = getListIndexByBaseDBName(baseDBName);
if(currentBaseDBIndex == -1) {
addBaseDB(baseDBName);
buildBaseLists();
currentBaseDBIndex = getListIndexByBaseDBName(baseDBName);
}
if (currentBaseDBIndex > -1) {
buildBaseLists();
}
currentDB = bdbList.get(currentBaseDBIndex);
}
/* Get the index according to the database name passed*/
private int getListIndexByBaseDBName(String baseDBName) {
if(mdbList==null)
mdbList = masterDB.getMasterDao().getAllDatabases();
int rv = -1; // default to not found
for(int i=0; i < mdbList.size();i++) {
if (mdbList.get(i).getDatabaseName().equals(baseDBName)) {
rv = i;
break;
}
}
return rv;
}
/* Output all rows from the BaseTable for data extracted by the BaseDaos getAllBaseTables */
private void logBaseData(List<BaseTable> baseTableList) {
Log.d(TAG,"Current Database Index is " + currentBaseDBIndex + " DB name is " + mdbList.get(currentBaseDBIndex).getDatabaseName());
for(BaseTable bt: baseTableList) {
Log.d(TAG,"\tMyData value is " + bt.getMydata());
}
}
private boolean isFirstTime(){
if (sharedPreferences.getBoolean("firstTime", true)) {
settings.putBoolean("firstTime", false);
settings.commit();
settings.apply();
return true;
} else {
return false;
}
}
}
BaseDatabase - databaseName 是由于空变量而发生错误的位置
@Database(
entities = {BaseTable.class},
version = 1
)
public abstract class BaseDatabase extends RoomDatabase {
public abstract BaseDao getBaseDao();
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static BaseDatabase getInstance(Context context, String databaseName) {
BaseDatabase instance = null;
if (databaseName != null) {
return Room.databaseBuilder(context, BaseDatabase.class, databaseName)
.allowMainThreadQueries()
.build();
}
return instance;
}
}
【问题讨论】:
-
哪一行导致错误?
-
使用像 liveData 等数据结构这样的观察者订阅者,并在获取数据时监听变化。
-
@Code-Apprentice - `BaseDatabase` 在
buildBaseLIst的for循环中初始化。 -
@Anshul - 谢谢,我没有尝试过
Observer,我会阅读的。 -
@svstackoverflow 请给出实际的代码行,而不是对其进行口头描述。
标签: java android android-room