Java 房间数据库查询

Java 房间数据库查询,java,android,android-room,Java,Android,Android Room,我不熟悉房间,我正在尝试查询我的数据库以从中获取行。我尝试通过用主键查询它,主键是id,但问题是我不知道如何从存储库返回目标对象 这是Dao @Query("SELECT * FROM targets WHERE id = :id LIMIT 1") Targets findTargetById(int id); 这是存储库类 public Targets findTarget (int id) { new findTargetByIDAsyncTask(mTargetsDao).e

我不熟悉
房间
,我正在尝试
查询
我的
数据库
以从中获取
。我尝试通过
主键
查询它,主键是id,但问题是我不知道如何从
存储库
返回目标
对象

这是
Dao

@Query("SELECT * FROM targets WHERE id = :id LIMIT 1")
Targets findTargetById(int id);
这是存储库类

 public Targets findTarget (int id) {
    new findTargetByIDAsyncTask(mTargetsDao).execute(id);

}

   private static class findTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private TargetsDao mAsyncTaskDao;

    findTargetByIDAsyncTask(TargetsDao dao) {
        mAsyncTaskDao = dao;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {

        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        super.onPostExecute(targets);
    }
}
公共目标findTarget(int-id){
新建findTargetByIDAsyncTask(mTargetsDao).execute(id);
}
私有静态类FindTargetByDaSyncTask扩展了AsyncTask{
私人TargetsDao mAsyncTaskDao;
findTargetByIDAsyncTask(TargetsDao dao){
mAsyncTaskDao=dao;
}
@凌驾
受保护目标doInBackground(整数…整数){
返回mAsyncTaskDao.findTargetById(整数[0]);
}
@凌驾
受保护的void onPostExecute(目标){
super.onPostExecute(目标);
}
}

返回结果有两种方法

第一种方法是调用
AsyncTask.get()
方法,但如果任务的时间超过5秒,它仍将保留一个主线程,从而导致ANR:

public Targets findTarget (int id) {
    return new findTargetByIDAsyncTask(mTargetsDao).execute(id).get();
}
第二种方法更复杂,但它不能保持主线程。您应该添加一个回调类:

public interface Callback {
        void onSuccess(Targets targets);
    }
存储库的每个方法都将如下所示:

public void findTarget (Callback callback, int id) {
        new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
    }
private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private final TargetsDao mAsyncTaskDao;
    private final Callback callback;

    FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
        mAsyncTaskDao = dao;
        this.callback = callback;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {
        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        callback.onSuccess(targets);
    }
}
AsynTask看起来是这样的:

public void findTarget (Callback callback, int id) {
        new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
    }
private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private final TargetsDao mAsyncTaskDao;
    private final Callback callback;

    FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
        mAsyncTaskDao = dao;
        this.callback = callback;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {
        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        callback.onSuccess(targets);
    }
}
私有静态类FindTargetByDaSyncTask扩展了AsyncTask{
私人最终目标Dao mAsyncTaskDao;
私有最终回调;
FindTargetByIDAsyncTask(TargetsDao dao,回调){
mAsyncTaskDao=dao;
this.callback=回调;
}
@凌驾
受保护目标doInBackground(整数…整数){
返回mAsyncTaskDao.findTargetById(整数[0]);
}
@凌驾
受保护的void onPostExecute(目标){
callback.onSuccess(目标);
}
}

关键是从后台线程获取数据/对象。您可以使用Android的
AsyncTask
ExecutorService
。一个简单的示例是,如果要获取用户名字符串,方法如下:

private String getName() {
    String name = null;
    try {
        name = Executors.newSingleThreadExecutor().submit(() ->
                userDao.fetchUserName()).get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return name;
}

您可以在存储库的onPostExecute方法中对目标执行任何操作。如果您想在assyncTask之外的任何地方使用它,那么您可以创建一个全局变量并影响OnPostExecute中的值。我有一个类似的用例。你的答案似乎简单而有效。但是我看到很多答案都是使用Callable和Future返回一个对象(参见)。感谢您对您的方法与可调用/未来方法的看法。