【问题标题】:Get rowId after inserted Room Persistence Library插入 Room Persistence Library 后获取 rowId
【发布时间】:2018-09-24 19:51:45
【问题描述】:

我所要做的就是从插入中获取返回值作为 long。我明白了,但它不起作用,我从返回的值中取回 0。我正在使用DAO、存储库和ViewModel,如Google CodeLabs 中所述。我关注了这个帖子Rowid after Insert in Room

播放器类

@Entity(tableName = "player_table")
public class Player {
    @PrimaryKey(autoGenerate = true)
    private long id;
    @NonNull
    @ColumnInfo(name = "username")
    private String username;
}

@Insert
long insert(Player player);

存储库

public long insert(Player player) {
    new insertAsyncTask(mPlayerDao).execute(player);
    rowId = player.getId();
return rowId;
}

视图模型

public long insert(Player player){
    rowId = mRepository.insert(player);
    return rowId;
}

活动

String playerString = editTextUsername.getText().toString();
Player player = new Player(playerString);
long rowId = mDreamViewModel.insert(player);

【问题讨论】:

  • 可以添加 Player 类吗?
  • @xcesco 完成...^^^
  • 我想知道它是否在 Repository/ViewModel 的返回中??
  • 这就是所有的代码?在 ViewModel#insert .. body 是 { long rowId=mRepo...insert(player);返回行号; } 还是 rowId 是在别的地方定义的?
  • @xcesco 是的,它只是设置在 viewModel long rowId 的顶部

标签: java android android-room


【解决方案1】:

问题是你在 AsyncTask 完成其后台插入工作之前返回 player.getId() ;您必须等到它为您提供正确的插入结果,这是使用线程安全的CountDownLatch 的建议解决方案,它使用.await() 方法暂停后续代码的执行,直到CountDownLatch 的计数达到0 ;每次调用 .countDown() 时它减 1。

public class Repository {

    private long rowId = -1;
    private CountDownLatch mLatch;

    public long insert(Player player) {
        mLatch = new CountDownLatch(1);
        new insertAsyncTask(mPlayerDao).execute(player);
        try {
            mLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i("LOG_TAG", String.valueOf(rowId));

        return rowId;
    }

    class insertAsyncTask extends AsyncTask<Player, Void, Void> {

        @Override
        protected Void doInBackground(Player... players) {
            rowId = mDatabase.getContactDAO().addContact(players[0]);
            mLatch.countDown();
            return null;
        }
    }

}

【讨论】:

    【解决方案2】:

    您的 Repository 类中的 insert 方法可以更改为:

    public long insert(Player player) {
        return new insertAsyncTask(mPlayerDao).execute(player).get();
    }
    

    我通过在 GitHub 上搜索 AsyncTasks 找到了this,其中最后两种类型为“Void,Long”,以及其他一些特定于 Room 的术语。

    在调试我自己的应用程序时,我看到 insert 方法中的 return 语句在 doInBackground 方法执行之前发生,这在我看到它发生后似乎很明显。

    【讨论】:

    • execute() 本身不是 get() 的替代方案(用于后台处理)吗?
    猜你喜欢
    • 2018-03-28
    • 1970-01-01
    • 2017-10-18
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    相关资源
    最近更新 更多