java - 应用程序在 RoomDb 中插入数据时崩溃
问题描述
我正在尝试在 RoomDb 中插入数据,但在数据插入时,即使我在线程中编写插入操作,应用程序也会崩溃。我有一个回收器视图适配器类,其中我有一个基于我想要添加的点击侦听器RoomDb 中的数据。
这是我的 logcat 错误:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
下面是我的代码:
ProductAdapter.class
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
List<Product> productList;
Context context;
public ProductAdapter(List<Product> productList, Context context) {
this.productList = productList;
this.context = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_row,parent,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Product product = productList.get(position);
holder.productName.setText(product.getName());
holder.productPrice.setText(product.getPrice());
Glide.with(context).load(product.getProduct_image()).placeholder(R.color.teal_200).into(holder.productImage);
holder.productCard.setAnimation(AnimationUtils.loadAnimation(context,R.anim.recycler_anim));
holder.addToCart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.tick.setVisibility(View.VISIBLE);
holder.addToCart.setVisibility(View.INVISIBLE);
((AppCompatActivity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
ProductDb db = ProductDb.getInstance(context);
CartProduct cartProduct = new CartProduct(product.get_id(),product.getName(),product.getProduct_image(),
product.getPrice(),"1");
db.productDao().insert(cartProduct);
}
});
}
});
}
@Override
public int getItemCount() {
return productList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView productImage,addToCart,tick;
TextView productName,productPrice;
CardView productCard;
public ViewHolder(@NonNull View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.productImage);
productName = itemView.findViewById(R.id.productName);
productPrice = itemView.findViewById(R.id.productPrice);
productCard = itemView.findViewById(R.id.productCard);
tick = itemView.findViewById(R.id.tick);
addToCart = itemView.findViewById(R.id.addToCart);
}
}
}
我该如何克服这个问题?
解决方案
当您尝试访问主线程上的数据库而不allowMainThreadQueries()
在数据库构建器中声明时,将引发此异常。如果你想在主线程上访问数据库,那么构造你的数据库对象,如下所示
Room.databaseBuilder(App.getInstance().getApplicationContext(), AppDatabase.class, DB_NAME).allowMainThreadQueries()
但不建议这样做。使用异步任务或任何其他后台线程进行数据库操作以获得流畅的用户体验
更新:
不推荐使用异步任务。您可以在此检查异步任务的更多替代方案
我使用 RxJava 进行数据库操作的示例代码是
Single.fromCallable(new Callable<Long>() {
@Override
public Long call() throws Exception {
return getProductDao().insert(product);
}
}).observeOn(Threads.ui())
.delaySubscription(1000, TimeUnit.MILLISECONDS)
.subscribeOn(Threads.io())
.subscribe(new RxGenListener<Long>() {
@Override
public void onSuccess(Long aLong) {
listener.onCallback(aLong);
}
});
推荐阅读
- awk - 在重复行上将列添加到 std 的 awk 命令
- xml - 通过 SOAPUI 中的登录方法传递凭据时出现错误消息
- unity3d - 在着色器图中使用渐变填充不规则形状
- linux - Windows 的“/sys/class/net”等价物是什么
- swift - Swift 5 URLSession API 类抛出奇怪的错误
- javascript - 是否可以通过 HTML 按钮在我的机器上执行 python 脚本?
- java - 为什么有些服务器为同一个文件返回不同的内容长度?
- r - 在看不见的数据上测试 ml 模型时出错,尝试合并数据集或省略 na
- python - Python Scrapy 在第一个元素 csspath() 处停止并且不会抓取其余部分
- c# - 逐帧/逐样本播放时同步音频和视频播放