[英]Room Database problem with Query in Dao class
所以在我的房間查詢中,我得到錯誤無法解析符號“照片”和無法解析符號“image_id”,例如房間無法識別此表和字段,錯誤發生在執行 MyImages 數據庫之后
我的圖像類:
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "photos")
public class MyImages {
@PrimaryKey(autoGenerate = true)
public int image_id;
public String image_title;
public String image_description;
public byte[] image;
public MyImages(String image_title, String image_description, byte[] image) {
this.image_title = image_title;
this.image_description = image_description;
this.image = image;
}
public void setImage_id(int image_id) {
this.image_id = image_id;
}
public int getImage_id() {
return image_id;
}
public String getImage_title() {
return image_title;
}
public String getImage_description() {
return image_description;
}
public byte[] getImage() {
return image;
}
}
MyImagesViewModel:
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class MyImagesViewModel extends AndroidViewModel {
private MyImagesRepository repository;
private LiveData<List<MyImages>> myImages;
public MyImagesViewModel(@NonNull Application application) {
super(application);
repository = new MyImagesRepository(application);
myImages = repository.getAllImages();
}
public void insert(MyImages myImage) {
repository.insert(myImage);
}
public void update(MyImages myImage) {
repository.update(myImage);
}
public void delete(MyImages myImage) {
repository.delete(myImage);
}
public LiveData<List<MyImages>> getAllMyImages() {
return myImages;
}
}
我的圖像存儲庫:
package com.example.photoalbum;
import android.app.Application;
import androidx.lifecycle.LiveData;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyImagesRepository {
private MyImagesDao myImagesDao;
private LiveData<List<MyImages>> imagesList;
ExecutorService executorService= Executors.newSingleThreadExecutor();
public MyImagesRepository(Application application)
{
MyImagesDatabase database=MyImagesDatabase.getInstance(application);
myImagesDao=database.myImagesDao();
imagesList= myImagesDao.getAllImages();
}
public void insert(MyImages myImages){
executorService.execute(new Runnable() {
@Override
public void run() {
myImagesDao.insert(myImages);
}
});
}
public void delete(MyImages myImages){
executorService.execute(new Runnable() {
@Override
public void run() {
myImagesDao.delete(myImages);
}
});
}
public void update(MyImages myImages){
executorService.execute(new Runnable() {
@Override
public void run() {
myImagesDao.update(myImages);
}
});
}
public LiveData<List<MyImages>>getAllImages(){
return imagesList;
}
}
我的圖片道:
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao
public interface MyImagesDao {
@Insert
void insert(MyImages myImages);
@Delete
void delete(MyImages myImages);
@Update
void update(MyImages myImages);
@Query("SELECT * FROM photos order by image_id asc")
LiveData<List<MyImages>> getAllImages();
}
我的圖像數據庫:
package com.example.photoalbum;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = MyImages.class,version = 1)
public abstract class MyImagesDatabase extends RoomDatabase {
private static MyImagesDatabase instance;
public abstract MyImagesDao myImagesDao();
public static synchronized MyImagesDatabase getInstance(Context context){
if(instance==null)
{
Room.databaseBuilder(context.getApplicationContext(), MyImagesDatabase.class,"photos_database")
.fallbackToDestructiveMigration()
.build();
}
return instance;
}
}
我以前寫過類似的代碼,我很困惑為什么它現在不起作用
錯誤:
Process: com.example.photoalbum, PID: 17024
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.photoalbum/com.example.photoalbum.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.photoalbum.MyImagesViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3835)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.photoalbum.MyImagesViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:236)
at com.example.photoalbum.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:8207)
at android.app.Activity.performCreate(Activity.java:8191)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:228)
at com.example.photoalbum.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:8207)
at android.app.Activity.performCreate(Activity.java:8191)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.example.photoalbum.MyImagesDao com.example.photoalbum.MyImagesDatabase.myImagesDao()' on a null object reference
at com.example.photoalbum.MyImagesRepository.<init>(MyImagesRepository.java:18)
at com.example.photoalbum.MyImagesViewModel.<init>(MyImagesViewModel.java:17)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:228)
at com.example.photoalbum.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:8207)
at android.app.Activity.performCreate(Activity.java:8191)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3808)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) ```
我相信這個問題並不是你所看到的真正問題:-
你可以忽略它。 但是,您可能會遇到其他問題:-
在MyImagesDatabase中,您沒有設置instance
,因此它將始終為空。
在MyImagesDao中使用default
似乎總是返回 null,而不是 MyImages 列表。
使用(為簡潔和方便添加到 MyImagedDatabase 的 .allowMainThreadQueries )和兩個額外的 @Query 注釋方法:-
/* ADDED for testing on Main Thread */
@Query("SELECT * FROM photos ORDER BY image_id ASC")
default List<MyImages> testGetAllImages() {
return null;
}
@Query("SELECT * FROM photos ORDER BY image_id ASC")
List<MyImages> test2GetAllImages();
並使用以下活動代碼:-
public class MainActivity extends AppCompatActivity {
MyImagesDatabase db;
MyImagesDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = MyImagesDatabase.getInstance(this);
dao = db.myImagesDao();
dao.insert(new MyImages("Image1","The first image", new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,}));
dao.insert(new MyImages("Image2","The second image", new byte[]{0,9,8,7,6,5,4,3,2,1,0,9,8,7,6,5,4,3,2,1}));
List<MyImages> milist = dao.testGetAllImages();
if (milist != null) {
for (MyImages mi : milist) {
Log.d("DBINFO_TEST1", "TITLE=" + mi.image_title + " DESC=" + mi.image_description + "ImageData=" + byteArrayToString(mi.image));
}
} else {
Log.d("DBINFO_TEST2","NULL returned from extract.");
}
milist = dao.test2GetAllImages();
if (milist != null) {
for (MyImages mi : milist) {
Log.d("DBINFO_TEST2", "TITLE=" + mi.image_title + " DESC=" + mi.image_description + "ImageData=" + byteArrayToString(mi.image));
}
} else {
Log.d("DBINFO_TEST1","NULL returned from extract.");
}
}
String byteArrayToString(byte[] ba) {
StringBuilder sb = new StringBuilder();
for (byte b: ba) {
sb.append(b);
}
return sb.toString();
}
}
然后輸出到日志的結果是:-
D/DBINFO_TEST1: NULL returned from extract.
D/DBINFO_TEST2: TITLE=Image1 DESC=The first imageImageData=01234567890123456789
D/DBINFO_TEST2: TITLE=Image2 DESC=The second imageImageData=09876543210987654321
即default
返回NULL,而沒有數據則按預期返回。
額外的
現在您已經包含了堆棧跟蹤,您將看到您有一個 NPE(空指針異常)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.example.photoalbum.MyImagesDao com.example.photoalbum.MyImagesDatabase.myImagesDao()' on a null object reference
如前所述。 如果您使用, instance
將始終為空:-
@Database(entities = MyImages.class,version = 1)
public abstract class MyImagesDatabase extends RoomDatabase {
private static MyImagesDatabase instance;
public abstract MyImagesDao myImagesDao();
public static synchronized MyImagesDatabase getInstance(Context context){
if(instance==null)
{
Room.databaseBuilder(context.getApplicationContext(), MyImagesDatabase.class,"photos_database")
.fallbackToDestructiveMigration()
.build();
}
return instance;
}
}
相反,您想使用:-
@Database(entities = MyImages.class,version = 1)
public abstract class MyImagesDatabase extends RoomDatabase {
private static MyImagesDatabase instance;
public abstract MyImagesDao myImagesDao();
public static synchronized MyImagesDatabase getInstance(Context context){
if(instance==null)
{
/* FOLLOWING LINE CHANGED to actual set the variable instance to not be null */
instance = Room.databaseBuilder(context.getApplicationContext(), MyImagesDatabase.class,"photos_database")
.fallbackToDestructiveMigration()
.build();
}
return instance;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.