当前位置: 首页 > 知识库问答 >
问题:

当我试图更新/编辑Sqlite数据库java.lang.IndexOutOfBoundsException时出现了这个错误:索引:0,大小:0可以帮助我吗

安泰平
2023-03-14
    Process: com.example.attendance, PID: 20112
    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.example.attendance.MainActivity.updateClass(MainActivity.java:135)
        at com.example.attendance.MainActivity.lambda$showUpdateDialog$4$MainActivity(MainActivity.java:131)
        at com.example.attendance.-$$Lambda$MainActivity$m9twlugKZZaVnr6kCG8LrRCoXMM.onClick(Unknown Source:4)
        at com.example.attendance.MyDialog.lambda$getUpdateClassDialog$1$MyDialog(MyDialog.java:94)
        at com.example.attendance.-$$Lambda$MyDialog$5v1iqgaO8riJO2phwUfadWXdoyM.onClick(Unknown Source:6)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
I/Process: Sending signal. PID: 20112 SIG: 9
package com.example.attendance;
    
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AlertDialog;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import android.content.Intent;
    import android.database.Cursor;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ImageButton;
    import android.widget.TextView;
    import android.widget.Toolbar;
    
    import com.google.android.material.floatingactionbutton.FloatingActionButton;
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
    
        FloatingActionButton floatingActionButton;
        RecyclerView recyclerView;
        ClassAdapter classAdapter;
        RecyclerView.LayoutManager layoutManager;
        ArrayList<ClassItem> classItems = new ArrayList<>();
        Toolbar toolbar;
        DbHelper dbHelper;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            dbHelper = new DbHelper(this);
    
            floatingActionButton = findViewById(R.id.fab_main);
            floatingActionButton.setOnClickListener(V -> showDialog());
    
            loadData();
    
    
            recyclerView = findViewById(R.id.att_list);
            recyclerView.setHasFixedSize(true);
            layoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            classAdapter = new ClassAdapter(this, classItems);
            recyclerView.setAdapter(classAdapter);
            classAdapter.setOnItemClickListener(position -> gotoItemActivity(position));
    
            setToolbar();
    
        }
    
        private void loadData() {
            Cursor cursor = dbHelper.getClassTable();
    
            classItems.clear();
            while (cursor.moveToNext()){
                int id = cursor.getInt(cursor.getColumnIndex(DbHelper.C_ID));
                String department = cursor.getString(cursor.getColumnIndex(DbHelper.CLASS_NAME_KEY));
                String subject = cursor.getString(cursor.getColumnIndex(DbHelper.SUBJECT_NAME_KEY));
    
                classItems.add(new ClassItem(id,department,subject));
            }
    
        }
    
        private void setToolbar() {
    
            toolbar = findViewById(R.id.toolbar);
    
            TextView title = toolbar.findViewById(R.id.tool_title);
            TextView subTitle = toolbar.findViewById(R.id.tool_sub_title);
            TextView samiTitle = toolbar.findViewById(R.id.tool_sami_title);
            ImageButton back = toolbar.findViewById(R.id.tool_back);
            ImageButton save = toolbar.findViewById(R.id.tool_save);
    
            title.setText("Attendance");
            subTitle.setVisibility(View.GONE);
            samiTitle.setVisibility(View.GONE);
            save.setVisibility(View.GONE);
            back.setOnClickListener(v -> onBackPressed());
    
        }
    
        private void gotoItemActivity(int position) {
            Intent intent = new Intent(this,StudentActivity.class);
            intent.putExtra("departmentName",classItems.get(position).getDepartment());
            intent.putExtra("subjectName",classItems.get(position).getSubject());
            intent.putExtra("position",position);
            startActivity(intent);
        }
    
        private void showDialog() {
            MyDialog dialog = new MyDialog();
            dialog.show(getSupportFragmentManager(),MyDialog.CLASS_ADD_DIALOG);
            dialog.setListener((department,subject)->addClass(department,subject));
    
        }
    
        private void addClass(String department, String subject) {
            long cid = dbHelper.addClass(department,subject);
            ClassItem classItem = new ClassItem(cid,department,subject);
            classItems.add(classItem);
            classAdapter.notifyDataSetChanged();
    
        }
    
        @Override
        public boolean onContextItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()){
                case 0:
                    showUpdateDialog(item.getGroupId());
                case 1:
                    deleteClass(item.getGroupId());
            }
            return super.onContextItemSelected(item);
        }
    
        private void showUpdateDialog(int position) {
            MyDialog updateDialog = new MyDialog();
            updateDialog.show(getSupportFragmentManager(),MyDialog.CLASS_UPDATE_DIALOG);
            updateDialog.setListener((department,subject)->updateClass(position,department,subject));
        }
    // when I try to Update the Data its don't work and the app will crash
        private void updateClass(int position, String department, String subject) {
            dbHelper.updateClass(classItems.get(position).getCid(),department,subject);
            classItems.get(position).setDepartment(department);
            classItems.get(position).setSubject(subject);
            classAdapter.notifyItemChanged(position);
        }
    
        private void deleteClass(int position) {
            dbHelper.deleteClass(classItems.get(position).getCid());
            classItems.remove(position);
            classAdapter.notifyItemRemoved(position);
        }
    } 

     package com.example.attendance;
        
        import android.content.Context;
        import android.view.ContextMenu;
        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 ClassAdapter extends RecyclerView.Adapter<ClassAdapter.ClassViewHolder> {
        
            private OnItemClickListener onItemClickListener;
        
            public interface OnItemClickListener {
                void onClick(int position);
            }
        
            public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
                this.onItemClickListener = onItemClickListener;
            }
        
            public ClassAdapter(Context context, ArrayList<ClassItem> classItems) {
                this.classItems = classItems;
                this.context = context;
            }
        
            ArrayList<ClassItem> classItems;
            Context context;
        
            public static class ClassViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {
        
        
        
                TextView department, subject;
        
                public ClassViewHolder(@NonNull View itemView,OnItemClickListener onItemClickListener) {
        
                    super(itemView);
        
                    department = itemView.findViewById(R.id.dep_tv);
                    subject = itemView.findViewById(R.id.sub_tv);
                    itemView.setOnClickListener(v -> onItemClickListener.onClick(getAdapterPosition()));
                    itemView.setOnCreateContextMenuListener(this);
        
                }
        
                @Override
                public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                    menu.add(getAdapterPosition(),0,0,"EDIT");
                    menu.add(getAdapterPosition(),1,0,"DELETE");
                }
            }
        
            @NonNull
            @Override
            public ClassViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.class_item, parent, false);
                return new ClassViewHolder(itemView, onItemClickListener);
            }
        
            @Override
            public void onBindViewHolder(@NonNull ClassViewHolder holder, int position) {
        
                holder.department.setText(classItems.get(position).getDepartment());
                holder.subject.setText(classItems.get(position).getSubject());
        
            }
        
            @Override
            public int getItemCount() {
                return classItems.size();
            }
        }

这里是数据库


    package com.example.attendance;

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

import androidx.annotation.Nullable;

public class DbHelper extends SQLiteOpenHelper {
    private static final int VERSION = 1;



    //Class table

    private static final String CLASS_TABLE_NAME= "CLASS_TABLE";
    public static final String C_ID= "_CID";
    public static final String CLASS_NAME_KEY= "CLASS_NAME";
    public static final String SUBJECT_NAME_KEY= "SUBJECT_NAME";

    private static final String CREATE_CLASS_TABLE=
            "CREATE TABLE " + CLASS_TABLE_NAME + "(" +
                    C_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
                    CLASS_NAME_KEY + " TEXT NOT NULL, " +
                    SUBJECT_NAME_KEY + " TEXT NOT NULL, " +
                    " UNIQUE ( " + CLASS_NAME_KEY + "," + SUBJECT_NAME_KEY + ")" +
                    ");";

    private static final String DROP_CLASS_TABLE = "DROP TABLE IF EXISTS "+CLASS_TABLE_NAME;
    private static final String SELECT_CLASS_TABLE = "SELECT * FROM "+CLASS_TABLE_NAME;

    //Student table

    private static final String STUDENT_TABLE_NAME= "STUDENT_TABLE";
    private static final String S_ID= "_SID";
    private static final String STUDENT_NAME_KEY= "STUDENT_NAME";
    private static final String STUDENT_ROLL_KEY= "ROLL";

    private static final String CREATE_STUDENT_TABLE=
            "CREATE TABLE "+ STUDENT_TABLE_NAME +
            "( "+
            S_ID+ " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "+
            C_ID + " TEXT NOT NULL, "+
            STUDENT_NAME_KEY + " TEXT NOT NULL, "+
            STUDENT_ROLL_KEY + " INTEGER, "+
            " FOREIGN KEY ( "+C_ID+ " ) REFERENCES "+ CLASS_TABLE_NAME + "("+C_ID+")"+
            ");";

    private static final String DROP_STUDENT_TABLE = "DROP TABLE IF EXISTS "+STUDENT_TABLE_NAME;
    private static final String SELECT_STUDENT_TABLE = "SELECT * FROM "+STUDENT_TABLE_NAME;

    //Status table

    private static final String STATUS_TABLE_NAME= "STATUS_TABLE";
    private static final String STATUS_ID= "_STATUS_ID";
    private static final String DATE_KEY= "STATUS_NAME";
    private static final String STATUS_KEY= "STATUS";

    private static final String CREATE_STATUS_TABLE=
            "CREATE TABLE "+STATUS_TABLE_NAME+
                    "("+
                    STATUS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "+
                    S_ID + " INTEGER NOT NULL, "+
                    DATE_KEY + " DATE NOT NULL, "+
                    STATUS_KEY + " TEXT NOT NULL, "+
                    " UNIQUE ( " + S_ID + "," + DATE_KEY + ")," +
                    " FOREIGN KEY ( "+ S_ID+ " ) REFERENCES "+ STUDENT_TABLE_NAME + "( "+S_ID+")"+
                    ");";

    private static final String DROP_STATUS_TABLE = "DROP TABLE IF EXISTS "+ STATUS_TABLE_NAME;
    private static final String SELECT_STATUS_TABLE = "SELECT * FROM "+ STATUS_TABLE_NAME;

    public DbHelper(@Nullable Context context) {
        super(context, "Attendance.db", null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_CLASS_TABLE);
        db.execSQL(CREATE_STUDENT_TABLE);
        db.execSQL(CREATE_STATUS_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        try {
            db.execSQL(DROP_CLASS_TABLE);
            db.execSQL(DROP_STUDENT_TABLE);
            db.execSQL(DROP_STATUS_TABLE);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    long addClass(String className,String subjectName){
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(CLASS_NAME_KEY,className);
        values.put(SUBJECT_NAME_KEY,subjectName);

        return database.insert(CLASS_TABLE_NAME,null,values);
    }

    Cursor getClassTable(){
        SQLiteDatabase database = this.getReadableDatabase();
        return database.rawQuery(SELECT_CLASS_TABLE,null);
    }

    int deleteClass(long cid){
        SQLiteDatabase database = this.getReadableDatabase();
        return database.delete(CLASS_TABLE_NAME,C_ID+"=?",new String[]{String.valueOf(cid)});
    }

    long updateClass(long cid,String className,String subjectName){
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(CLASS_NAME_KEY,className);
        values.put(SUBJECT_NAME_KEY,subjectName);

        return database.update(CLASS_TABLE_NAME,values,C_ID+"=?",new String[]{String.valueOf(cid)});
    }

}

共有1个答案

赵雪峰
2023-03-14

删除表后,忘记在onupgrade方法中再次创建它们。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        try {
            db.execSQL(DROP_CLASS_TABLE);
            db.execSQL(DROP_STUDENT_TABLE);
            db.execSQL(DROP_STATUS_TABLE);
            onCreate(db);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

另外,在每次调用.getwritabledatabase().getreadabledatabase()时调用.close()方法也是一个好主意。这里有一个例子...

long addClass(String className, String subjectName){
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(CLASS_NAME_KEY,className);
        values.put(SUBJECT_NAME_KEY,subjectName);
        database.close();
        long id = database.insert(CLASS_TABLE_NAME,null,values);
        return id;
    }

希望能有所帮助,快乐的编码!

 类似资料: