【问题标题】:Cursor null after adding data to database将数据添加到数据库后光标为空
【发布时间】:2016-05-21 16:10:23
【问题描述】:

当我的应用第一次加载时,数据被添加到应用中,用户可以使用他/她想要的任何东西。 问题是当我向同一个表中添加更多数据时,可以说我在更新中添加了更多数据。 然后代码开始崩溃并告诉我:

android.database.CursorIndexOutOfBoundsException:请求索引 0, 大小为 0

我发现我的光标是空的,但我不知道为什么。

数据库没有打开,我已经正常关闭了。 这是我的代码:

添加到数据库部分:

public class Database {


    private Dbhelper dbhelper;
    SQLController dbcon;
    private SQLiteDatabase database;
    Context context;

    public Database(Dbhelper dbhelper, SQLController dbcon, SQLiteDatabase database, Context context) {
        this.dbhelper = dbhelper;
        this.database = database;
        this.dbcon = dbcon;
        this.context = context;
    }


    public boolean addToDatabase() {
        boolean isTrue = false;
        ///
        try {

            dbcon.open();
            int plan_i = dbcon.countPlanStock().getCount();
            dbcon.close();

            if (plan_i < 3) {

                dbcon.open();
                dbcon.deletePlanSAll();
                dbcon.close();

                //REST = REST
                dbcon.open();
                dbcon.insertPlanStock("Newbie", "Free", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");
                dbcon.close();

                dbcon.open();
                dbcon.insertPlanStock("Alpha 10", "Pro version", "ic_alphaten", "14 Days", "1 8 5 12 4 10 REST 11 REST 1 6 REST 2 5", "false false false false false false false false false false false false false false");
                dbcon.close();

                dbcon.open();
                dbcon.insertPlanStock("Alpha V2", "Pro version", "ic_alphav2", "30 Days", "1 3 11 10 13 REST REST 5 4 11 12 8 REST REST 3 7 13 11 REST 13 12 REST REST 6 12 4 1 REST 12 13", "false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false");
                dbcon.close();
            }


            dbcon.open();
            int workout_i = dbcon.countDataS().getCount();
            dbcon.close();

            if (workout_i < 17) {

                dbcon.open();
                dbcon.deleteAllFromStockWorkouts();
                dbcon.close();

                dbcon.open();
                dbcon.insertDataStock("INTENSE MMA CIRCUIT", " ENDURANCE ", " DEFINITION ", " CORE ", "16min", "NO EQUIPMENT REQUIRED", "3",
                        "pushups uppercuts slow_pushups quick_punches",//round 1
                        "jump_squat_180 burpee_hill_climb short_jumps",//round 2
                        "leg_raises tyson_neck_raise spartan_pushups",//round 3
                        "",//round 4
                        "",//round 5
                        "",//round 6
                        "",//round 7
                        "",//round 8
                        "",//round 9
                        "",//round 10
                        "",//round 11
                        "",//round 12


                        "40000",//rest 1
                        "40000",//rest 2
                        "40000",//rest 3
                        "",//rest 4
                        "",//rest 5
                        "",//rest 6
                        "",//rest 7
                        "",//rest 8
                        "",//rest 9
                        "",//rest 10
                        "",//rest 11
                        "",//rest 12

                        "10x 30x 5x 50x",//reps round 1
                        "5x 10x 10x",//reps round 2
                        "10x 5x 10x",//reps round 3
                        "",//reps round 4
                        "",//reps round 5
                        "",//reps round 6
                        "",//reps round 7
                        "",//reps round 8
                        "",//reps round 9
                        "",//reps round 10
                        "",//reps round 11
                        "",//reps round 12

                        "intense_mma_circuit_1",//round exercises 1
                        "intense_mma_circuit_2",//round exercises 2
                        "intense_mma_circuit_3",//round exercises 3
                        "",//round exercises 4
                        "",//round exercises 5
                        "",//round exercises 6
                        "",//round exercises 7
                        "",//round exercises 8
                        "",//round exercises 9
                        "",//round exercises 10
                        "",//round exercises 11
                        "",//round exercises 12

                        "300000",//reps round 1 main
                        "300000",//reps round 2 main
                        "300000",//reps round 3 main
                        "",//reps round 4 main
                        "",//reps round 5 main
                        "",//reps round 6 main
                        "",//reps round 7 main
                        "",//reps round 8 main
                        "",//reps round 9 main
                        "",//reps round 10 main
                        "",//reps round 11 main
                        "",//reps round 12 main


                        "10",//rest exercise round 1 main
                        "10",//rest exercise round 2 main
                        "10",//rest exercise round 3 main
                        "",//rest exercise round 4 main
                        "",//rest exercise round 5 main
                        "",//rest exercise round 6 main
                        "",//rest exercise round 7 main
                        "",//rest exercise round 8 main
                        "",//rest exercise round 9 main
                        "",//rest exercise round 10 main
                        "",//rest exercise round 11 main
                        "",//rest exercise round 12 main
                        "0",//workout type


                        "- - -",//Exercise Rest Round 1
                        "- -",//Exercise Rest Round 2
                        "- -",//Exercise Rest Round 3
                        "",//Exercise Rest Round 4
                        "",//Exercise Rest Round 5
                        "",//Exercise Rest Round 6
                        "",//Exercise Rest Round 7
                        "",//Exercise Rest Round 8
                        "",//Exercise Rest Round 9
                        "",//Exercise Rest Round 10
                        "",//Exercise Rest Round 11
                        ""//Exercise Rest Round 12


                );
                dbcon.close();


                ......
            }



        } finally {
            isTrue = true;
        }


        return isTrue;
    }


}

有一个异步任务可以解决这个问题,我只是这个类作为助手。

后面添加数据时出现问题的Adapter类:

public class PlanAdapter extends AppCompatActivity {
    private Toolbar toolbar;
    private Dbhelper dbhelper;
    SQLController dbcon;
    private SQLiteDatabase database;
    SQLController adapter;
    String[] wokrouts_A;
    String wokrouts_S;

    public String[] isDone_A;
    public String isDone_S;
    public boolean isDone[];
    private ProgressBar progressBar;
    public int bool_counter = 0;

    private String Plan_Name = "TEST";
    private TextView Plan_Days_Coutner;

    RecyclerView recyclerView;
    PlanRecyclerAdapter ca;

    int current_day = 0;

    String[] workout_name_shortener;


    private DBhelper dbhelper_l;
    private SQLiteDatabase database_l;
    SQLiteController dbcon_l;
    String date = new SimpleDateFormat("d.M.yyyy").format(new Date());

    ProgressBar pm_navigation;
    List<Integer> Tab_Colour = new ArrayList<>();

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


        adapter = new SQLController(this);
        dbcon = new SQLController(this);
        dbhelper = new Dbhelper(this);
        database = dbhelper.getWritableDatabase();


        dbcon_l = new SQLiteController(this);
        dbhelper_l = new DBhelper(this);
        database_l = dbhelper_l.getWritableDatabase();

        Intent intent = getIntent();
        Plan_Name = intent.getStringExtra("plan_info");

        toolbar = (Toolbar) findViewById(R.id.app_bar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Typeface faceRobotoMedium = Typeface.createFromAsset(getResources().getAssets(), "Roboto-Medium.ttf");
        TextView TitleBarCustom = (TextView) findViewById(R.id.toolbar_title);
        TitleBarCustom.setTypeface(faceRobotoMedium);

        TitleBarCustom.setText("" + Plan_Name);
        getSupportActionBar().setTitle(null);

        Plan_Days_Coutner = (TextView) findViewById(R.id.plan_coutner_id);
        Plan_Days_Coutner.setTypeface(faceRobotoMedium);


        recyclerView = (RecyclerView) findViewById(R.id.recyclerList);
        LinearLayoutManager llm = new LinearLayoutManager(this);
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(llm);
        ca = new PlanRecyclerAdapter(generateWorkouts(), isDone, bool_counter, Plan_Name, getApplicationContext(), dbhelper, dbcon, database);
        //ca.setClickListener(this);
        recyclerView.setAdapter(ca);

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setProgress(current_day);
        progressBar.setMax(isDone.length);

        if (current_day == isDone.length) {
            Plan_Days_Coutner.setText("" + isDone.length + " DAYS" + " PLAN COMPLETED");


        } else {
            Plan_Days_Coutner.setText("DAY " + current_day + "/" + isDone.length);
        }


        for (boolean n : isDone) {
            Log.d("Seud", "_" + n);
        }


    }

    private ArrayList<PlanRecycler> generateWorkouts() {
        ArrayList<PlanRecycler> palettes = new ArrayList<>();

        String[] allColumns = new String[]{Dbhelper.PLAN_ID,
                Dbhelper.PLAN_NAME,
                Dbhelper.PLAN_UNDER_TEXT,
                Dbhelper.PLAN_DURATION,
                Dbhelper.PLAN_IMAGE,
                Dbhelper.PLAN_WOKROUTS_ID,
                Dbhelper.PLAN_IS_FINISHED
        };

        Cursor cursor_s = database.query(Dbhelper.TABLE_PLAN_STOCK, allColumns, "_name=\'" + Plan_Name + "\'", null, null, null, null, "1");

        if (cursor_s != null) {
            cursor_s.moveToFirst();
            wokrouts_S = cursor_s.getString(5);
            isDone_S = cursor_s.getString(6);
        }

        try {
            wokrouts_A = wokrouts_S.split("\\s+");
            Log.d("Workouts_name", "" + wokrouts_A);
        } catch (PatternSyntaxException ex) {
        }

        try {
            isDone_A = isDone_S.split("\\s+");
        } catch (PatternSyntaxException ex) {
        }



        Boolean_Generator(isDone_A);

        if (cursor_s.moveToFirst()) {
            do {

                for (int i = 0; i < wokrouts_A.length; i++) {

                    palettes.add(new PlanRecycler(
                            Workout_Name(wokrouts_A[i]), Workout_Name_Holder(wokrouts_A[i]), Tab_Colour.get(i)

                    ));

                }
            } while (cursor_s.moveToNext());
        }
        cursor_s.close();

        return palettes;
    }

    //Workout Name Decider
    public String Workout_Name_Holder(String id_S) {
        String workout_name = "";
        if (id_S.equals("REST")) {
            workout_name = "Rest";
        } else {
            String[] allColumns = new String[]{
                    Dbhelper.WORKOUTS_ID,
                    Dbhelper.WORKOUT_NAME,

            };
            Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");


            if( cursor != null && cursor.moveToFirst() ){
                workout_name = cursor.getString(1);
                cursor.close();
            }

            /*
            if (cursor != null) {
                cursor.moveToFirst();
                //id = cursor.getString(2);
                workout_name = cursor.getString(1);
            }
            cursor.close();
            */
        }
        return workout_name;
    }

    //Workout Name Decider
    public String Workout_Name(String id_S) {
        String workout_name = "";
        String template = "";
        String holder = "";


        if (id_S.equals("REST")) {
            workout_name = "Rest";
        } else {
            String[] allColumns = new String[]{
                    Dbhelper.WORKOUTS_ID,
                    Dbhelper.WORKOUT_NAME,
                    Dbhelper.WORKOUT_TIME

            };
            Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

            if( cursor != null && cursor.moveToFirst() ){
                Log.d("Cursor_info","not_null");
                if (cursor.getString(1).contains("SPARTAN SPECIALE ADVANCED") || cursor.getString(1).contains("SPARTAN SPECIALE BEGINNER") || cursor.getString(1).contains("TRICEPS SMASHER REPS")) {
                    template = "(reps)";
                } else {
                    template = "(" + cursor.getString(2) + ")";
                }

            }else{
                Log.d("Cursor_info","null");
            }


            try {
                workout_name_shortener = cursor.getString(1).split("\\s+");
                cursor.close();
                int counter = 0;
                for (int i = 0; i < workout_name_shortener.length; i++) {

                    if (workout_name_shortener[i].equals("TIMER") || workout_name_shortener[i].equals("REPS") || workout_name_shortener[i].equals("ADVANCED") || workout_name_shortener[i].equals("BEGINNER") && counter != 0) {
                        break;
                    } else {
                        holder += workout_name_shortener[i] + " ";
                    }
                    counter++;
                }
            }catch (Exception e){
                Log.d("Exception_log",""+e);
            }



            workout_name = holder + template;
            //cursor.close();
        }

        return workout_name;
    }


    public void Boolean_Generator(String[] boolean_S) {

        int counter = 0;

        isDone = new boolean[boolean_S.length];
        for (int i = 0; i < boolean_S.length; i++) {

            if (boolean_S[i].equals("true")) {
                bool_counter++;
                isDone[i] = Boolean.TRUE;

                Tab_Colour.add(getResources().getColor(R.color.siva_3));

            } else {


                if(counter<1){
                    Tab_Colour.add(getResources().getColor(R.color.siva_1));
                }else{
                    Tab_Colour.add(getResources().getColor(R.color.siva_2));
                }
                counter++;
                isDone[i] = Boolean.FALSE;
            }
        }

        for (int i = 0; i < isDone.length; i++) {
            Log.d("bools_a", "" + isDone[i]);
            if (isDone[i] == true) {
                current_day++;
            }
        }

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                back_pressed();
                return true;
            case R.id.action_renew:

                Toast.makeText(this, "Plan renewed", Toast.LENGTH_SHORT).show();

                dbcon.open();

                if(Plan_Name.equals("Newbie")){

                    dbcon.updatePlanStock("Newbie", "UNDER TEXT", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");

                }else if(Plan_Name.equals("Alpha 10")){

                    dbcon.updatePlanStock("Alpha 10", "UNDER TEXT", "ic_alphaten", "14 Days", "1 2 3 4 5 6 7 8 9 10", "false false false false false false false false false false");

                }else if(Plan_Name.equals("Alpha V2")){

                    dbcon.updatePlanStock("Alpha V2", "Pro version", "ic_alphav2", "30 Days", "1 3 11 10 13 REST REST 5 4 11 12 8 REST REST 3 7 13 11 REST 13 12 REST REST 6 12 4 1 REST 12 13", "false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false");

                }

                dbcon.close();

                dbcon_l.open();
                dbcon_l.insertData("" + Plan_Name + " Plan", "" + date);
                dbcon_l.close();


                Bundle ExerciseBundle = new Bundle();
                ExerciseBundle.putString("plan_info", Plan_Name);

                Intent i = new Intent(/* FirstActivity.this */
                        getApplicationContext(),
                        PlanAdapter.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                i.putExtras(ExerciseBundle);

                startActivity(i);

                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public boolean onCreateOptionsMenu(Menu menu) {

        if (current_day == isDone.length) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.menu_delete, menu);
        }

        return true;
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        back_pressed();

    }


    public void back_pressed() {
        Intent test = new Intent(getApplication(), MainActivity.class);
        test.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(test);
    }

}

附加日志猫:

进程:com.spartanbodyweightworkouts,PID:14142 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.spartanbodyweightworkouts/com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter}: android.database.CursorIndexOutOfBoundsException:请求索引 0, 大小为 0 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 在 android.app.ActivityThread.-wrap11(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 引起:android.database.CursorIndexOutOfBoundsException:索引 0 请求,大小为 0 在 android.database.AbstractCursor.checkPosition(AbstractCursor.java:460) 在 android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136) 在 android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50) 在 com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.Workout_Name(PlanAdapter.java:247) 在 com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.generateWorkouts(PlanAdapter.java:174) 在 com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.onCreate(PlanAdapter.java:109) 在 android.app.Activity.performCreate(Activity.java:6251) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 在 android.app.ActivityThread.-wrap11(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

【问题讨论】:

  • 当然可以,但是问题表明我将数据添加到数据库后光标为空,我可以在其他部分使用它并且相同的光标不为空。
  • 我也没有哈哈哈,你知道它会是什么吗。你在我的代码中看到任何问题,任何关键部分吗?
  • 在哪部分对不起?

标签: java android android-sqlite


【解决方案1】:

在代码的底部,您已将cursor.close; 注释掉。

Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

if( cursor != null && cursor.moveToFirst() ){
.../...
workout_name = holder + template;
//cursor.close();

您关闭它太快了,如果 try 和 catch 失败,您还需要检查游标是否已关闭。在“if”或“try”的情况下,保持资源的整洁是个好主意。


public String Workout_Name(String id_S) {
    String workout_name = "";
    String template = "";
    String holder = "";


    if (id_S.equals("REST")) {
        workout_name = "Rest";
    } else {
        String[] allColumns = new String[]{
                Dbhelper.WORKOUTS_ID,
                Dbhelper.WORKOUT_NAME,
                Dbhelper.WORKOUT_TIME

        };
        Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

        if( cursor != null && cursor.moveToFirst() ){
            Log.d("Cursor_info","not_null");
            if (cursor.getString(1).contains("SPARTAN SPECIALE ADVANCED") || cursor.getString(1).contains("SPARTAN SPECIALE BEGINNER") || cursor.getString(1).contains("TRICEPS SMASHER REPS")) {
                template = "(reps)";
            } else {
                template = "(" + cursor.getString(2) + ")";
            }

        }else{
            Log.d("Cursor_info","null");
        }


        try {
            workout_name_shortener = cursor.getString(1).split("\\s+");
            cursor.close();
            int counter = 0;
            for (int i = 0; i < workout_name_shortener.length; i++) {

                if (workout_name_shortener[i].equals("TIMER") || workout_name_shortener[i].equals("REPS") || workout_name_shortener[i].equals("ADVANCED") || workout_name_shortener[i].equals("BEGINNER") && counter != 0) {
                    break;
                } else {
                    holder += workout_name_shortener[i] + " ";
                }
                counter++;
            }
        }catch (Exception e){
            Log.d("Exception_log",""+e);
        }



        workout_name = holder + template;
        //cursor.close();
    }

    return workout_name;
}

我建议在您的应用程序中使用您的 sqlite 助手的单个实例。在这里查看更多详细信息:

Is it OK to have one instance of SQLiteOpenHelper shared by all Activities in an Android application?

【讨论】:

  • 游标在int counter = 0上方关闭。当我向它添加数据时,游标为空。我的意思是数据库
  • 对不起,我不是以英语为母语的人,您能解释一下这部分“还考虑使用数据库助手的单个实例来避免内存泄漏”
【解决方案2】:

问题是,当我从表中删除所有记录时,当我添加回数据时,它会切换 id。但在计划中,我要求对不存在的 id 进行锻炼。

 dbcon.open();
                dbcon.insertPlanStock("Newbie", "Free", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");
                dbcon.close();

数字需要更改为锻炼名称

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2023-04-03
    • 2019-10-19
    • 2018-01-22
    相关资源
    最近更新 更多