我正在使用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());
}
});
}
}
现在我明白这对一些人来说可能是一个愚蠢的问题,我可能会因此受到评判,但除了互联网,我没有其他来源可以学习。非常感谢所有的帮助。
您的代码很好,应该可以正常工作。
有几件事要检查:
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'
也谢谢你在这里检查答案,这也可能指导你。