![](/img/trans.png)
[英]Issue using 2 different recyclerView in 2 activities with 1 room database
[英]Room Database, RecyclerView and Concurrency problems
我陷入了一個 Android 應用程序的開發中,該應用程序必須將數據存儲在 SQLite 數據庫(房間數據庫)中。 我想要做的是從 SQLite 表中檢索數據並將其顯示在 RecyclerView 上。 但是,根據我修改代碼的方式,我會得到三種不同的錯誤輸出:
1.- 如果我將數據庫訪問放在主線程中,錯誤消息類似於:“數據庫訪問不能從主線程完成,因為應用程序可能會凍結”。
2.- 如果我在不同的線程中編寫數據庫訪問代碼,它會告訴我視圖只能由創建它們的線程訪問。
3.- 如果我將數據庫訪問和 Recycler Adapter 聲明放在不同的線程中,我會得到如此可怕的“空指針異常”,因為它找不到發送到 Adapter 對象的 ArrayList。
這是我的代碼:
menuPrincipal.java:
public class menuPrincipal extends AppCompatActivity {
public BaseDatosApp basedatos;
public List<Lista> listas;
public RecyclerView rcv;
public RecyclerView.LayoutManager gestorLayouts;
private Intent actividadPrincipal;
private Button btnNuevaLista, btnAbrirLista, btnGuardarLista, btnBorrarLista;
private ManejaBotonesMnuPrinc manejador;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_principal);
basedatos = Room.databaseBuilder(getApplicationContext(), BaseDatosApp.class, "lista-compra").build();
Thread hilo=new Thread(new Runnable(){
@Override
public void run() {
listas = new ArrayList<>();
RecyclerAdapter rca;
basedatos.listaDao().insert(new Lista("Otra lista nueva"));
listas = basedatos.listaDao().getAll();
rca = new RecyclerAdapter(listas);
rcv = findViewById(R.id.recycler_listcom);
rcv.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rcv.setAdapter(rca);
}
});
btnNuevaLista = findViewById(R.id.btnNuevaLista);
btnAbrirLista = findViewById(R.id.btnAbrirLista);
btnGuardarLista = findViewById(R.id.btnGuardarLista);
btnBorrarLista = findViewById(R.id.btnBorrarLista);
btnNuevaLista.setOnTouchListener(manejador);
btnAbrirLista.setOnTouchListener(manejador);
btnGuardarLista.setOnTouchListener(manejador);
btnBorrarLista.setOnTouchListener(manejador);
manejador = new ManejaBotonesMnuPrinc();
actividadPrincipal = new Intent(this, MainActivity.class);
}
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ListasViewHolder>{
public List<Lista> listasElem;
public RecyclerAdapter(List<Lista> listas){
listasElem=listas;
}
@NonNull
@Override
public ListasViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context miContexto = parent.getContext();
int layoutIdParaListItem = R.layout.elemento_texto;
LayoutInflater inflador=LayoutInflater.from(miContexto);
boolean attachToParentRapido=false;
View vista = inflador.inflate(layoutIdParaListItem,parent,attachToParentRapido);
ListasViewHolder viewHolder = new ListasViewHolder(vista);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ListasViewHolder holder, int position){
holder.elementoListaView.setText(listasElem.get(position).getNombre());
}
@Override
public int getItemCount() {
return listasElem.size();
}
class ListasViewHolder extends RecyclerView.ViewHolder{
TextView elementoListaView;
public ListasViewHolder(@NonNull View itemView) {
super(itemView);
elementoListaView = itemView.findViewById(R.id.elementoLista_tv);
}
}
}
請,如果您有任何建議,請告訴我。
我建議為此任務使用 rxJava 2 https://medium.com/androiddevelopers/room-rxjava-acb0cd4f3757在您的情況下,代碼將如下所示
db.employeeDao().getAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Employee>>() {
@Override
public void accept(List<Employee> employees) throws Exception {
// set data to adapter
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.