当从片段的OnResume调用时,Android SQliteOpenHelper数据库索引出界

问题描述 投票:0回答:1

我对android应用程序开发还是相当陌生,stackoverflow是一个很好的资源,所以谢谢你!问题。我遇到了SQliteDatabase / OpenHelper / AssetHelper很难解决的问题,因为我无法复制许多应用程序用户在我的设备或任何android studio模拟设备上遇到的错误,因此我将向您展示此代码为我工作,但不为其他人工作,我也不知道为什么。

当我的应用程序从数据库(资产文件夹中)填充的List中获取值时,我的用户有时会获得indexoutofboundsexception(我相信)。因此,似乎数据库未正确加载。我相信问题可能与我在Fragment生命周期的DBProgressAccess中获得DatabaseAccess类OnResume的实例时传递的上下文有关。

我没有做太多的努力来解决这个问题,仅是因为崩溃很少发生(仅在我的android 6.0手机上发生过一次),但是我从Google那里收到有关其他android设备(包括android在内)频繁崩溃的报告6.0)。我崩溃的堆栈跟踪来自Google开发人员控制台。

我有一个在应用程序启动时加载的片段。在从showSets12()调用的onResume()方法中(我看到indexoutofbounds错误),我访问了用户得分的数据库:

    private void showSets12()
    {
        DBProgressAccess dbProgressAccess = DBProgressAccess.getInstance(getActivity());
        dbProgressAccess.openUserProgressDb();
        dbProgressAccess.getDayValues();
        int scoreToday = dbProgressAccess.getScores().get(0); <--I think the error comes from this
        ...
        dbProgressAccess.closeUserProgressDb();

    }

在公共DBProgressAccess类中,我具有:

public class DBProgressAccess {

    private SQLiteOpenHelper openHelper;
    private SQLiteDatabase database;
    private static DBProgressAccess instance;

    private List<String> dates;
    private List<Integer> scores;
    private List<String> times;

    public static final String TABLE_NAME = "UserProgress";

    public List<Integer> getScores() {return scores;}


    private DBProgressAccess(Context context) {
        this.openHelper = new DBProgressHandler(context);
    }

    public static DBProgressAccess getInstance(Context context)
    {
        Log.d(TAG, "getInstance");
        if(instance == null) {
            instance = new DBProgressAccess(context);
        }
        return instance;
    }


    /**
     * Open the database connection.
     */
    public void openUserProgressDb() {
        Log.d(TAG, "openUserProgress");
        this.database = openHelper.getWritableDatabase();
    }


    /**
     * Is todays date included in the database? If not, create it and search the database to populate lists for times and scores
     */
    public void getDayValues()
    {
        if (checkIfDateExists()) {
            Cursor cursor = searchDayProgress();
            searchDatabase(cursor);
        }
        else
        {
            createDayEntry();
            Cursor cursor = searchDayProgress();
            searchDatabase(cursor);
        }
    }

    /**
     * Check to see if there is a record in the database for today 
     */
    public boolean checkIfDateExists()
    {
        Cursor cursor = searchDayProgress();
        if(cursor.getCount() <= 0)
        {
            cursor.close();
            return false;
        }
        cursor.close();
        return true;
    }


    /**
     * Insert todays date into the database
     */
    private void createDayEntry()
    {
        Date today = Calendar.getInstance().getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String todayString = formatter.format(today);
        int score = 0;
        String time = "0:00:0";

        ContentValues cv = new ContentValues();
        cv.put("date", todayString);
        cv.put("score", score);
        cv.put("time", time);

        database.insert(TABLE_NAME, null, cv);
    }


    /**
     * Find the database record for today
     */
    private Cursor searchDayProgress() {
        String whereQuery = "SELECT * FROM UserProgress WHERE date = date('now')";
        Log.d(TAG, "searchWeekProgress " + whereQuery);
        return database.rawQuery(whereQuery, null);
    }

    /**
     * Populate lists of time, date and progress taken from the database
     */
    public void searchDatabase(Cursor cursor)
    {
        List<String> listDate = new ArrayList<>();
        List<Integer> listUserProgress = new ArrayList<>();
        List<String> listTime = new ArrayList<>();

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            listDate.add(cursor.getString(cursor.getColumnIndex("date")));
            listUserProgress.add(cursor.getInt(cursor.getColumnIndex("score")));
            listTime.add(cursor.getString(cursor.getColumnIndex("time")));
            cursor.moveToNext();
        }
        cursor.close();

        setDates(listDate);
        setScores(listUserProgress);
        setTimes(listTime);
    }

    private void setDates(List<String> dates) {this.dates = dates;}
    private void setScores(List<Integer> scores) {this.scores = scores;}
    private void setTimes(List<String> times) {this.times = times;}

}


我相信List<string>变量结果为空。

我希望我可以输入更具体的代码,但是Google开发人员控制台堆栈跟踪尚不清楚。

我收到的错误来自Google开发人员控制台,而不是android studio,因为我无法在我的设备或任何仿真设备上复制该问题。

java.lang.RuntimeException: 
  at android.app.ActivityThread.performResumeActivity (ActivityThread.java:3573)
   at android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3613)
   at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2862)
   at android.app.ActivityThread.-wrap12 (ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1574)
   at android.os.Handler.dispatchMessage (Handler.java:110)
   at android.os.Looper.loop (Looper.java:203)
   at android.app.ActivityThread.main (ActivityThread.java:6364)
   at java.lang.reflect.Method.invoke (Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1076)
   at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:937)

Caused by: java.lang.IndexOutOfBoundsException: 
  at java.util.ArrayList.get (ArrayList.java:411)
  at org.ieltstutors.academicwordlist.AcademicWordListFragment.showSets12 (AcademicWordListFragment.java)
  at org.ieltstutors.academicwordlist.AcademicWordListFragment.access$000 (AcademicWordListFragment.java)
  or                     .access$200 (AcademicWordListFragment.java)
  or                     .drawCircularLockedProgress (AcademicWordListFragment.java)
  or                     .onCreateView (AcademicWordListFragment.java)
  or                     .openCloseSet (AcademicWordListFragment.java)
  or                     .showCircularScores (AcademicWordListFragment.java)
  or                     .showScores (AcademicWordListFragment.java)
  or                     .updateScores (AcademicWordListFragment.java)
  at org.ieltstutors.academicwordlist.AcademicWordListFragment.onResume (AcademicWordListFragment.java)

很遗憾,这是我对错误的全部信息。

因此IndexOutOfBoundsException来自showSets12。错误可能是由于为getInstance使用了错误的上下文吗?还是来自getWriteableDatabase?为什么有时可以正确访问数据库,但有时却不能正确访问?我记得当应用程序启动时当该应用程序在手机上崩溃时,我立即尝试在我的朋友手机上打开该应用程序,但它也崩溃了,之前从未发生过崩溃。巧合?

唷!任何帮助是极大的赞赏。谢谢!

android database sqlite indexoutofboundsexception
1个回答
0
投票

仅在调用Activity onResume()或onPause()时才调用片段onResume()或onPause()。它们与活动紧密相关。如果要将片段添加到活动中时要执行某些操作,则可以使用OnAttach()或其他片段生命周期

阅读本文以了解片段Lifecycle

© www.soinside.com 2019 - 2024. All rights reserved.