我正在使用房间数据持久性库创建一个Android应用程序,但是我很难弄清楚如何在新线程中查询数据库并将值返回给主线程...
例如,我的ProductDAO中有一个方法可以通过他的barCode检索一个产品:
@Query("SELECT * FROM Product WHERE barCode = :barCode")
Product getProductById (String barCode);
在另一堂课中我试过这个:
public Product getProduct(final String barcode){
final Product[] product = new Product[1];
new Thread(new Runnable() {
@Override
public void run() {
product[0] = db.inventory().getProductById(barcode);
}
});
return product[0];
}
但结果总是null
,我不知道如何从主线程中的getProductById
返回值。我确定数据库配置是正确的,因为当我使用allowMainThreadQueries()
构建数据库时,我的所有查询都在主线程中工作
从新线程插入产品时也遇到同样的问题:
public void AddProduct(final Product product){
new Thread(new Runnable() {
@Override
public void run() {
db.inventory().insertOneProduct(product);
}
});
}
因为它似乎没有插入任何东西。
非常感谢!!
答案 0 :(得分:2)
问题似乎与此代码有关:
public void AddProduct(final Product product){
new Thread(new Runnable() {
@Override
public void run() {
db.inventory().insertOneProduct(product);
}
});
}
虽然您已创建了一个线程,但您没有调用start方法。所以改成它:
public void AddProduct(final Product product){
new Thread(new Runnable() {
@Override
public void run() {
db.inventory().insertOneProduct(product);
}
}).start();
}
然后它应该有用。
作为旁注,您应该使用Async Task而不是线程,因为AsyncTask旨在与android线程模型一起使用,并允许您在单独的线程上工作时轻松跟踪进度以及其他好处。
答案 1 :(得分:-1)
这是使用AsyncTask的示例。由于实际在不同线程中运行的唯一方法是“ doInBackground()”,因此很容易将数据写回UI-Thread。 AsyncTask类签名的第一个参数定义“ doInBackground(Param param)”方法的参数类型。在这里可以传递对调用类/活动的引用,这是您的UI-Thread。让任务做您想做的事情,然后将结果返回给onPostExecute(Result result)方法。在这里,您可以简单地在UI线程上调用任何方法并传递数据。 通过从您的UI线程中调用以下内容来启动整个过程。
new AllUsersLoader().execute(this);
public class AllUsersLoader extends AsyncTask<Context, Void, List<User>>{
private AppDataBase db;
private UserDao dao;
private List<User> users;
private MainActivity con;
/**
* This method actually runs on a Non-UI-Thread.
* @param contexts A reference to the MainActivity
* @return Result that is passed to onPostExecute()
*/
@Override
protected List<User> doInBackground(Context... contexts) {
this.con = (MainActivity) contexts[0];
db = Room.databaseBuilder(con.getApplicationContext(), AppDataBase.class, con.getResources().getString(R.string.db_scema_name)).build();
dao = db.getUserDao();
users = dao.getAllUsers();
db.close();
return users;
}
/**
* This method is again part of the UI-Thread but waits till it receives the result from doInBackground()
* @param users
*/
@Override
protected void onPostExecute(List<User> users) {
super.onPostExecute(users);
con.updateRecyclerView(users); //a method of the UI-thread expecting the result
}
} // end of class
您还可以将所有内容限制在一个嵌套类或Listener中,并保存自己通过上下文的操作。