英文:
Android Room: error: setValue(T) has protected access in LiveData
问题
我正在尝试开始进行Android开发和Room数据库操作。
我正在制作一个音乐播放器应用,其中包含播放列表和文件浏览器,可以将歌曲添加到当前播放列表。
我将播放列表保存在一个Room数据库中。
我遇到的问题是,第一次运行程序时,数据库中没有任何数据。
我想要查询数据库以获取上次打开的播放列表,但如果数据库中没有播放列表,我想创建一个空的PlayList对象。
7 public class PlayListRepository
8 {
9 public PlayListRepository(Application application)
10 {
11 _application = application;
12 }
13
14 public LiveData<PlayListWithTracks> getPlayList(int playListId)
15 {
16 if (_appDao == null) {
17 InitDb();
18 }
19 LiveData<PlayListWithTracks> livePlayListWithTracks = _appDao.getByIdWithTracks(playListId);
20 if (livePlayListWithTracks.getValue() == null) {
21 livePlayListWithTracks.setValue(new PlayListWithTracks());
22 }
23 return livePlayListWithTracks;
24 }
25
26
27 private void InitDb()
28 {
29 AppDatabase db = AppDatabase.getDatabase(_application);
30 _appDao = db.appDao();
31 }
32
33 private Application _application;
34 private AppDao _appDao;
35 }
第21行无法编译。它显示`error: setValue(T)在LiveData中具有受保护的访问权限`。
我的`AppDao.getByIdWithTracks`方法如下:
@Dao
public interface AppDao
{
@Transaction
@Query("SELECT * FROM PlayList WHERE Id = :id")
LiveData<PlayListWithTracks> getByIdWithTracks(int id);
}
我尝试将`livePlayListWithTracks`强制转换为`MutableLiveData<PlayListWithTracks>`,但这会导致运行时错误`androidx.room.RoomTrackingLiveData无法转换为androidx.lifecycle.MutableLiveData`。
我尝试将其转换为`RoomTrackingLiveData`,但是Android Studio无法识别`androidx.room`导入。
我是否走错了路?
编辑: 这是PlayListWithTracks:
public class PlayListWithTracks
{
@Embedded
public PlayList playList;
@Relation(
parentColumn = "id",
entityColumn = "playListId"
)
public List<Track> tracks = new Vector<Track>();
}
英文:
I'm trying to get up and running with Android development and Room.
I'm making a music player app with playlists and a file browser that will be able to add tracks to the current playlist.
I'm saving the playlists in a Room database.
I'm running into the problem of running the program from the first time, and there not being any data in the database.
I want to query the database for the last playlist opened, but if there are no playlists in the database, I want to create an empty PlayList object.
7 public class PlayListRepository
8 {
9 public PlayListRepository(Application application)
10 {
11 _application = application;
12 }
13
14 public LiveData<PlayListWithTracks> getPlayList(int playListId)
15 {
16 if (_appDao == null) {
17 InitDb();
18 }
19 LiveData<PlayListWithTracks> livePlayListWithTracks = _appDao.getByIdWithTracks(playListId);
20 if (livePlayListWithTracks.getValue() == null) {
21 livePlayListWithTracks.setValue(new PlayListWithTracks());
22 }
23 return livePlayListWithTracks;
24 }
25
26
27 private void InitDb()
28 {
29 AppDatabase db = AppDatabase.getDatabase(_application);
30 _appDao = db.appDao();
31 }
32
33 private Application _application;
34 private AppDao _appDao;
35 }
Line 21 doesn't compile. It says error: setValue(T) has protected access in LiveData
.
My AppDao.getByIdWithTracks
method looks like this:
@Dao
public interface AppDao
{
@Transaction
@Query("SELECT * FROM PlayList WHERE Id = :id")
LiveData<PlayListWithTracks> getByIdWithTracks(int id);
}
I've tried casting livePlayListWithTracks
to MutableLiveData<PlayListWithTracks>
, but that gives me a runtime error of androidx.room.RoomTrackingLiveData cannot be cast to androidx.lifecycle.MutableLiveData
I've tried casting it to RoomTrackingLiveData
, but Android Studio doesn't recognize the androidx.room
import.
Am I on the wrong track or what?
Edit: Here is PlayListWithTracks:
public class PlayListWithTracks
{
@Embedded
public PlayList playList;
@Relation(
parentColumn = "id",
entityColumn = "playListId"
)
public List<Track> tracks = new Vector<Track>();
}
答案1
得分: 2
LiveData
代表数据库中的数据。如果您从应用程序的任何其他部分修改数据库中的条目,则您的 LiveData
将反映该更改。试图为 LiveData
设置另一个值是没有意义的。
如果您不需要观察数据的更改,那么您可能可以在数据访问对象中直接返回对象。就像这样:
@Dao
public interface AppDao
{
@Transaction
@Query("SELECT * FROM PlayList WHERE Id = :id")
PlayListWithTracks getByIdWithTracks(int id);
}
也许更好的方法是,如果数据库中不存在播放列表条目,则在数据库中创建一个新的播放列表条目,然后访问该条目。这意味着您可以为数据库添加一个新的 PlayListWithTracks
实体,其中包含函数接收的 id
,然后访问该实体。
英文:
LiveData
represents the data in your database. If you modify that entry in the database from any other part of your application your LiveData
will reflect that change. It serves no purpose to try and set another value to the LiveData
.
If you do not require to observe changes in the Data then you can probably return the object in the Data Access Object. Like so:
@Dao
public interface AppDao
{
@Transaction
@Query("SELECT * FROM PlayList WHERE Id = :id")
PlayListWithTracks getByIdWithTracks(int id);
}
Perhaps the better approach would be to create a new playlist entry in the database if it does not exist and then access that entry. Meaning that you could add a new PlayListWithTracks
entity to the database with the id
received in the function and then access that entity
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论