提问者:小点点

如何从资产预填充房间数据库?


我正在使用SQLiteOpenHelper类编写一个应用程序,并决定使用Room重新构建它来实现MVVM模式,以获得一些额外的可用性。我的第一个问题是Room需要使用. createFromAsset("数据库/data_table.db")从资产文件夹中加载数据库文件。它应该将其复制到设备,然后所有进程都从那里开始,但它不会根据需要复制它,开发人员网站不会指定更多的调用方法。这是Database类,其中解释了用于学习目的的每种方法,因为我正在学习过程中。

@Database(entities = MarkerObject.class, version = 1, exportSchema = false)
public abstract class MarkerDatabase extends RoomDatabase {

    /**We create the instance so we wouldn't create multiple instances
     of the database and use the same instance throughout the application
     which is accessed through the static variable **/
    private static MarkerDatabase instance;

    /**
     *This is used to access the Dao,
     * no body is provided because Room takes care of that,
     * abstract classes don't have methods but the room generates it because of the @Dao annotation.
     */
    public abstract MarkerDao markerDao();

    /**
     * This method creates a single instance of the database,
     * then we can call this method from the outside so we have a handle to it.
     * Synchronized means that only one thread at a time can access the database
     * eliminating creating multiple instances.
     */
    public static synchronized MarkerDatabase getInstance(Context context){

        /** we want to instantiate the database
         * only if we don't have an instance, thus the if condition */
        if (instance == null) {
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    MarkerDatabase.class, "locations_table")
                    .createFromAsset("database/locations_table.db")
                    .build();
        }
        return instance;
    }
} 

那个DAO

@Dao
public interface MarkerDao {

    @Query("SELECT * FROM locations_table")
    LiveData<List<MarkerObject>> getAllMarkers();

}

存储库

public class MarkerRepository {
  
    private MarkerDao markerDao;
    private LiveData<List<MarkerObject>> allMarkers;

    public MarkerRepository(Application application){
    
    MarkerDatabase markerDatabase = MarkerDatabase.getInstance(application);
    
    markerDao = markerDatabase.markerDao();
  
    allMarkers = markerDao.getAllMarkers();
}
public LiveData<List<MarkerObject>> getAllMarkers(){return allMarkers; }

}

视图模型

public class MarkerViewModel extends AndroidViewModel {
  
    private MarkerRepository repository;
    private LiveData<ArrayList<MarkerObject>> allMarkers;

    /**
     * We use the application as context in the constructor
     * because the ViewModel outlives the activities lifecycle.
     * To avoid memory leaks we use application as context instead of activities or views.
     */
    public MarkerViewModel(@NonNull Application application) {
        super(application);
        
        repository = new MarkerRepository(application);
        allMarkers = repository.getAllMarkers();
    }
    public LiveData<ArrayList<MarkerObject>> getAllMarkers(){
        return allMarkers;
    }
}

的主要活动

public class MainActivity extends AppCompatActivity {
    private MarkerViewModel markerViewModel;

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

        TextView textView = findViewById(R.id.textView);

        markerViewModel = new ViewModelProvider(this).get(MarkerViewModel.class);
        markerViewModel.getAllMarkers().observe(this, new Observer<List<MarkerObject>>() {
            @Override
            public void onChanged(List<MarkerObject> markerObjects) {
                textView.setText(markerObjects.toString());
            }
        });
    }
}

现在我明白这对一些人来说可能是一个愚蠢的问题,我可能会因此受到评判,但除了互联网,我没有其他来源可以学习。非常感谢所有的帮助。


共1个答案

匿名用户

您的代码很好,应该可以正常工作。

有几件事要检查:

  • 首先:确保location_table. db文件存在于app\src\main\资产\数据库目录下

它应该将其复制到设备,然后所有进程都从那里开始,但它没有按要求复制它,开发者网站没有指定更多的内容,只是如何调用它

  • 第二个:createFromAsset()

更新

错误是java. lang.RuntimeException:无法创建类com.example.room text first.MarkerViewModeL的实例

首先,我看不出您的新共享代码有任何问题。我只需要您确保您在模块gradle文件中具有以下依赖项:

implementation 'androidx.fragment:fragment:1.2.2'
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'androidx.lifecycle:lifecycle-service:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'

而不是被弃用的:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'

也谢谢你在这里检查答案,这也可能指导你。