androidsqliteandroid-listview

Sqlite android stopped processing update, delete


I have an activity with a listview and one button, I use sqlite as a database

private SQLiteDatabase db;
db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS tasx (id INTEGER primary key autoincrement, name TEXT, complOn INTEGER, steps INTEGER)");

button adds items to list

public void onClick(DialogInterface dialog,int id) {
String a = ("'");
Log.d("message",inputName.getText().toString() + inpuSteps.getText());
db.execSQL("INSERT OR IGNORE INTO tasx VALUES (NULL, " + a + inputName.getText().toString() +a +", "+a +inpuSteps.getText() +a+", "+a+ inputCompleted.getText()+a+");");
updateDB();
}

as well as the UpdateDB method, which simply updates the displayed list

private void updateDB(){
        ArrayList<DataModel> list = new ArrayList<>();
        Cursor query = db.rawQuery("SELECT * FROM tasx;", null);
        CustomAdapter adapter = new CustomAdapter(list, getApplicationContext());
        while(query.moveToNext()){
            String name = query.getString(1);
            String age = String.valueOf(query.getInt(2));
            String stp = String.valueOf(query.getInt(3));
            list.add(new DataModel(name, age + "/"+stp));
        }
        lv.setAdapter(adapter);
//        query.close();
    }

and the last thing I have problems with is clicking on a list item

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final ImageView photo = (ImageView) view.findViewById(R.id.plus);
                onCompliteTask((int) id);
                photo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                    }
                });
        }});

private void onCompliteTask(Integer i){
        Runnable runnable = () -> {
            db.execSQL("UPDATE tasx SET complOn = complOn + 1 WHERE id = "+ i);
            Log.d("click","successuful" + i);
        };
        Runnable runnable1 = () -> {
            db.execSQL("DELETE FROM tasx WHERE id = "+i+" AND complOn >= steps");
            Log.d("click","successuful" + i);

        };
        Thread thread = new Thread(runnable);
        Thread thread1 = new Thread(runnable1);
        thread.start();
        thread1.start();
//        updateDB();
    }

Moreover, when I was simply checking the capabilities and performance, it worked, but for some reason unknown to me it stopped. I thought that sqlite does not support multiple queries at the same time, and first moved it to a separate class, then to separate threads, but this did not help. Logs are displayed, requests are not executed. I will be glad for any help or hint, this is my first time working with sqlite


Solution

  • The adapter is not a Cursor Adapter (it cannot be as a CursorAdapter requires a column name _id and also a Cursor passed to it not an Array/List).

    As such, the long id WILL VERY LIKELY NOT be the id of the row, it will be the position of the displayed row in the List/Array with 0 as the first Item, 1 as the next and so on. Rarely will the position equate to the id of the underlying row.

    So you need to either get the id from the object at the position (either position or id, they effectively have the same value but id is a long) or use a CursorAdapter (requiring something like SELECT *,id AS _id .... or perhaps SELECT rowid AS _id,* ....) so that the int (should really be long) is the correct value passed to the onCompliteTask method.


    Demo (for convenience using a CursorAdapter i.e SimpleCursorAdapters, also uses the main thread)


    Note two tables and thus two ListViews. The difference being the tasx table uses AUTOINCREMENT, tasz does not.

    The core code for the demo is within the Activity and is:-

    public class MainActivity extends AppCompatActivity {
        SQLiteDatabase db;
        SimpleCursorAdapter sca,scaz;
        Cursor csr,csrz;
        ListView lv_c, lv_cz;
        Button insertButton;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            lv_c = this.findViewById(R.id.lv_c);
            lv_cz = this.findViewById(R.id.lv_cz);
            insertButton = this.findViewById(R.id.insert);
    
    
            db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
            db.execSQL("CREATE TABLE IF NOT EXISTS tasx (id INTEGER primary key autoincrement, name TEXT, complOn INTEGER, steps INTEGER)");
            db.execSQL("CREATE TABLE IF NOT EXISTS tasz (id INTEGER primary key, name TEXT, complOn INTEGER, steps INTEGER)");
    
            insertRows();
            insertButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    insertRows();
                }
            });
        }
    
        void insertRows() {
            ContentValues cv = new ContentValues();
            cv.put("name","NAME_" + String.valueOf(System.currentTimeMillis()));
            cv.put("complOn",100);
            cv.put("steps",300);
            db.insert("tasx",null,cv);
            db.insert("tasz",null,cv);
            setOrRefreshAdapters();
        }
    
        void setOrRefreshAdapters() {
    
            csr = db.rawQuery("SELECT id AS _id,* FROM tasx",null);
            int _id_ix = csr.getColumnIndex(BaseColumns._ID);
            int id_ix = csr.getColumnIndex("id");
            int name_ix = csr.getColumnIndex("name");
            int complOn_ix = csr.getColumnIndex("complOn");
            int steps_ix = csr.getColumnIndex("steps");
    
            csrz = db.rawQuery("SELECT id AS " + BaseColumns._ID + ",* FROM tasz",null);
    
            if (sca == null) {
                sca = new SimpleCursorAdapter(this,
                        R.layout.dm_listview_row,csr,
                        new String[]{"id","name","complOn","steps"},
                        new int[]{R.id.text1,R.id.text2,R.id.text3,R.id.text4},0
                );
                lv_c.setAdapter(sca);
                lv_c.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        Log.d("LV_SCA","Clicked on pos=" +  String.valueOf(i) + "  l=" + l);
                    }
                });
                lv_c.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        db.execSQL("DELETE FROM tasx WHERE id=?",new String[]{String.valueOf(l)});
                        setOrRefreshAdapters(); /* Refresh the list after the deletion */
                        return true;
                    }
                });
            } else {
                sca.swapCursor(csr);
            }
            if (scaz == null) {
                scaz = new SimpleCursorAdapter(this,
                        R.layout.dm_listview_row,csrz,
                        new String[]{"id","name","complOn","steps"},
                        new int[]{R.id.text1,R.id.text2,R.id.text3,R.id.text4},0
                );
                lv_cz.setAdapter(scaz);
                lv_cz.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        Log.d("LV_SCAZ","Clicked on pos=" +  String.valueOf(i) + "  l=" + String.valueOf(l));
                    }
                });
                lv_cz.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        db.execSQL("DELETE FROM tasz WHERE id=?", new String[]{String.valueOf(l)});
                        setOrRefreshAdapters(); /* Refresh the list after the deletion */
                        return true;
                    }
                });
            } else {
                scaz.swapCursor(csrz);
            }
        }
    }
    

    the dm_listview_row layout is a simple 4 textview with id's text1, text2, text3 and text4.

    When a ListView item is:-

    When run (again note after a few runs so a few rows exist and some don't):-

    enter image description here

    Now if each row is clicked in turn (upper then the lower), the log includes:-

    2024-02-03 18:14:45.425 D/LV_SCA: Clicked on pos=0  l=1
    2024-02-03 18:14:47.159 D/LV_SCAZ: Clicked on pos=0  l=1
    
    2024-02-03 18:14:49.249 D/LV_SCA: Clicked on pos=1  l=2
    2024-02-03 18:14:50.895 D/LV_SCAZ: Clicked on pos=1  l=2
    
    2024-02-03 18:14:52.591 D/LV_SCA: Clicked on pos=2  l=4
    2024-02-03 18:14:54.258 D/LV_SCAZ: Clicked on pos=2  l=4
    
    2024-02-03 18:14:56.601 D/LV_SCA: Clicked on pos=3  l=5
    2024-02-03 18:14:59.100 D/LV_SCAZ: Clicked on pos=3  l=5
    
    2024-02-03 18:15:03.112 D/LV_SCA: Clicked on pos=4  l=7
    2024-02-03 18:15:04.747 D/LV_SCAZ: Clicked on pos=4  l=6
    
    2024-02-03 18:15:06.970 D/LV_SCA: Clicked on pos=5  l=8
    2024-02-03 18:15:08.393 D/LV_SCAZ: Clicked on pos=5  l=7
    
    2024-02-03 18:15:10.145 D/LV_SCA: Clicked on pos=6  l=9
    2024-02-03 18:15:11.637 D/LV_SCAZ: Clicked on pos=6  l=8