O
O
Orkhan Hasanli2018-05-19 18:50:09
Android
Orkhan Hasanli, 2018-05-19 18:50:09

How to fix OOM in recyclerview?

Good day.
I use a ready-made sqlite database and recyclerview for data output. (For the database I use SqliteAssetHelper instead of SqliteOpenHelper). And now, in essence: when the application was launched, I received NPE, now I have corrected this moment, but now in MainActivity I get OOM (out of memory). To be honest, I don’t know which way to dig, since the OOM cases in the recyclerview described on the net are related to images and Glide, Picssso, etc. The problem occurs when the adapter is connected. Below is the code for the Oncreate method in MainActivity, adapter and POD. NPE received due to the fact that he simply forgot to create a database instance. But I don’t understand why OOM ...
The Oncreate () method

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

 db = new DatabaseOpenHelper(this);
//        db.openDatabase();
//        db.getAllData();
//        Log.d(DRUGS_LOG, "Доступ к БД открыт");

        //Log.d(DRUGS_LOG, "T:" + medicationsAdapter.getItemCount());

        //medicationList =  new ArrayList<Medication>();

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        // Подключаем адаптер
        medicationsAdapter = new MedicationsAdapter(db.getAllData(), this);
        recyclerView.setAdapter(medicationsAdapter);

        // Добавляем разделитель для recyclerView
        recyclerView.addItemDecoration(new DividerItemDecoration(
                getApplicationContext()
        ));
    }

Adapter:
public class MedicationsAdapter extends RecyclerView.Adapter<MedicationsAdapter.MedicationsViewHolder> {

    private static final String DRUGS_LOG = "mylogs";
    private Context mContext;
    private List<Medication> medicationList;

    // Конструктор
    public MedicationsAdapter(List<Medication> medicationsList, Context mContext) {
        this.medicationList = medicationsList;
        this.mContext = mContext;
    }

    public class MedicationsViewHolder extends RecyclerView.ViewHolder {

        public TextView tradeNameText;
        public TextView intNameText;
        public ImageButton imageButton;

        public MedicationsViewHolder(final View itemView) {
            super(itemView);

            tradeNameText = itemView.findViewById(R.id.medication_trade_name);
            intNameText = itemView.findViewById(R.id.medication_int_name);
            imageButton = itemView.findViewById(R.id.favorite_button);

            imageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.d(DRUGS_LOG, "Была нажата кнопка \"Избранное\"");

                }
            });
        }
    }

    @Override
    public MedicationsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.medication_item, parent, false);
        return new MedicationsViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MedicationsViewHolder holder, int position) {

        holder.tradeNameText.setText(medicationList.get(position).get_tradeName());
        holder.intNameText.setText(medicationList.get(position).get_intName());
    }

    @Override
    public int getItemCount() {
        return medicationList.size();
    }
}

POJO-
POJO Medication
public class Medication {
    int _id;
    String _tradeName, _intName, _atc, _description;

    // Конструкторы
    public Medication(int _id, String _tradeName, String _intName, String _atc, String _description) {
        this._id = _id;
        this._tradeName = _tradeName;
        this._intName = _intName;
        this._atc = _atc;
        this._description = _description;
    }
    public Medication() {}
    public Medication(String _tradeName, String _intName) {
        this._tradeName = _tradeName;
        this._intName = _intName;
    }

    // Геттеры
    public int get_id() {
        return _id;
    }

    public String get_tradeName() {
        return _tradeName;
    }

    public String get_intName() {
        return _intName;
    }

    public String get_atc() {
        return _atc;
    }

    public String get_description() {
        return _description;
    }

    // Сеттеры

    public void set_id(int _id) {
        this._id = _id;
    }

    public void set_tradeName(String _tradeName) {
        this._tradeName = _tradeName;
    }

    public void set_intName(String _intName) {
        this._intName = _intName;
    }

    public void set_atc(String _atc) {
        this._atc = _atc;
    }

    public void set_description(String _description) {
        this._description = _description;
    }
}
Log
05-19 15:46:12.111 30278-30278/info.md7.dermanlar D/dalvikvm: GC_BEFORE_OOM freed <1K, 1% free 98187K/98304K, paused 85ms, total 85ms
05-19 15:46:12.111 30278-30278/info.md7.dermanlar E/dalvikvm-heap: Out of memory on a 24-byte allocation.
05-19 15:46:12.111 30278-30278/info.md7.dermanlar I/dalvikvm: "main" prio=5 tid=1 RUNNABLE
...
...
...
05-19 15:46:12.111 30278-30278/info.md7.dermanlar I/dalvikvm:     at info.md7.sqlite.DatabaseOpenHelper.getAllData(DatabaseOpenHelper.java:144)
05-19 15:46:12.111 30278-30278/info.md7.dermanlar I/dalvikvm:     at info.md7.dermanlar.MainActivity.onCreate(MainActivity.java:52)
....
.....
.....
05-19 15:46:12.247 30278-30278/info.md7.dermanlar D/dalvikvm: GC_BEFORE_OOM freed 0K, 1% free 98187K/98304K, paused 70ms, total 70ms
05-19 15:46:12.247 30278-30278/info.md7.dermanlar E/dalvikvm-heap: Out of memory on a 28-byte allocation.
05-19 15:46:12.247 30278-30278/info.md7.dermanlar I/dalvikvm: "main" prio=5 tid=1 RUNNABLE
....
....
....
05-19 15:46:13.051 30278-30278/info.md7.dermanlar E/AndroidRuntime: FATAL EXCEPTION: main
                                                                    java.lang.OutOfMemoryError: [memory exhausted]
                                                                        at dalvik.system.NativeStart.main(Native Method)
05-19 15:46:13.051 25243-25254/system_process W/ActivityManager:   Force finishing activity info.md7.dermanlar/.MainActivity
05-19 15:46:13.555 25243-25347/system_process I/qtaguid: Failed write_ctrl(s 1 10023) res=-1 errno=1

Could you tell me in which direction to dig? And what could be wrong?
Thanks in advance for your replies!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Varakosov, 2018-05-19
@azerphoenix

Apparently, for some reason you unload the entire contents of the database into memory. What for?
There is a very simple approach, in onBindViewHolder() you get the required entry from the database and fill in the list element, this only requires the number of the element in the list, which is obtained as holder.getLayoutPosition().

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question