Search code examples
javaandroidandroid-recyclerviewandroid-sqlite

Java.outOfMemory exception in a simple app


I am using recyclerview to display some textviews. I am collecting data from the SQLite database.

This is the helper class for database:

package com.example.a7minuteworkoutdemo;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

import java.util.ArrayList;

public class DBHelper extends SQLiteOpenHelper {
    static final String TABLE_NAME="History";
    static final int VERSION=1;
    static final String  ID="id";
    static final String DATE="date";
    public DBHelper(@Nullable Context context, @Nullable SQLiteDatabase.CursorFactory factory) {
        super(context, TABLE_NAME, factory, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql="CREATE TABLE " + TABLE_NAME + " ( " + ID + " INTEGER PRIMARY KEY, " + " "+DATE+" VARCHAR2(50))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void addDate(String date){
        ContentValues cv=new ContentValues();
        cv.put(DATE, date);
        SQLiteDatabase db=getWritableDatabase();
        db.insert(TABLE_NAME, null, cv);
    }

    public ArrayList<String> seeDate(){
        ArrayList<String> dates=new ArrayList<>();
        String sql="SELECT * FROM "+TABLE_NAME;
        SQLiteDatabase db=getReadableDatabase();
        Cursor c=db.rawQuery(sql, null);
        while (c.moveToFirst()){
            String date=c.getColumnName(c.getColumnIndex(DATE));
            dates.add(date);//logcat showing error here
            c.moveToNext();
        }
        c.close();
        return dates;
    }
}

This is the code where I insert some data into database:

DBHelper dbHelper=new DBHelper(this, null);
        Calendar calendar=Calendar.getInstance();
        Date date=calendar.getTime();
        SimpleDateFormat sdf=new SimpleDateFormat("dd MMM yyyy hh:mm:ss", Locale.getDefault());
        String dateToday=sdf.format(date);
        dbHelper.addDate(dateToday);

This is the adapter class: package com.example.a7minuteworkoutdemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> {

    Context context;
    ArrayList<String> data;

    public HistoryAdapter(Context context, ArrayList<String> data) {
        this.context = context;
        this.data = data;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.history_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.tvTime.setText(data.get(position));
    }

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

    static class ViewHolder extends RecyclerView.ViewHolder{
        TextView tvTime;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tvTime=itemView.findViewById(R.id.tvTime);
        }
    }
}

This is where I query the database and attach recyclerview and adapter:

RecyclerView rvHistory=findViewById(R.id.rvHistory);
        DBHelper dbHelper=new DBHelper(this, null);
        HistoryAdapter ha=new HistoryAdapter(this, dbHelper.seeDate());//logcat showing error here
        rvHistory.setAdapter(ha);
        rvHistory.setLayoutManager(new LinearLayoutManager(this));

Other questions here have told about using images but I am only using a textview. Why is it causing an outOfMemory exception and what is the solution?


Solution

  • In the Database Helper DBHelper method seeDate you have :

        while (c.moveToFirst()){
            String date=c.getColumnName(c.getColumnIndex(DATE));
            dates.add(date);
            c.moveToNext();
        }
    

    This will move to the first row every iteration and will never end (until something like memory gives) if there are any rows in the Cursor. Change it to be :-

        while (c.moveToNext()){
            String date=c.getColumnName(c.getColumnIndex(DATE));
            dates.add(date);
        }
    

    In which case it will move to the next row (from "before the first row" to the first row if there are any rows in the Cursor on the first iteration of the loop) until there are no more rows.