Проблемы с базой данных, RecyclerView и параллелизмом - PullRequest
0 голосов
/ 09 марта 2020

Я застрял в разработке приложения Android, которое должно хранить данные в базе данных SQLite (Room Database). Я пытаюсь извлечь данные из таблицы SQLite и отобразить их в RecyclerView. Однако, в зависимости от того, как я изменяю код, я получаю три разных сообщения об ошибках:

1.- Если я помещаю доступ к базе данных в основной поток, сообщение об ошибке выглядит примерно так: «Доступ к базе данных не должен быть сделано из основного потока, потому что приложение может зависнуть ".

2.- Если я напишу код доступа к базе данных в другом потоке, он скажет мне, что представления могут быть затронуты только тем потоком, который их создал .

3.- Если я помещу и доступ к базе данных, и декларацию адаптера Recycler в другой поток, я получу столь опасающееся «исключение нулевого указателя», потому что оно просто не может найти отправляемый 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);
        }
    }
}

Пожалуйста, если у вас есть предложения, дайте мне знать.

1 Ответ

0 голосов
/ 09 марта 2020

Я рекомендую использовать rx Java 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
       }
   });
...