代码之家  ›  专栏  ›  技术社区  ›  Tushar Thakur

从sqlite读取值时出现Android Stackoverflow错误

  •  2
  • Tushar Thakur  · 技术社区  · 7 年前

    我正在使用指纹读取器读取员工指纹。 一旦 morphoDatabase.identify 执行时,指纹读取器等待员工指纹。 采集指纹后,我从指纹读取器数据库中获取employeeId。 现在,我想从我的sqlite数据库中获取该员工的详细信息,并显示问候语。 在这之后,我再次开始识别过程。

    问题: 当我的身份号码达到100左右时,我的应用程序就崩溃了。

    我添加了logcat错误。

    Thread commandThread = (new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                identifyThreadMethod();
                Log.e("Identification Thread", "Completed");
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }));
    
    
    
    private void identifyThreadMethod() {
    
                int ret = 0;
                try {
                    ret = morphoDatabase.identify(timeout, far, coder,
                            detectModeChoice, matchingStrategy, callbackCmd,
                            DashboardActivity.this, resultMatching, 2, morphoUser);
                } catch (Exception e) {
                    Log.e("Exception", "Identification");
                }
    
                if(ret == 0) {
                    String employeeId= morphoUser.getField(0);
                    getEmployee(employeeId);
                }
    
                if (retvalue != -11) { // reader database not empty
                        if (!flag) {
                            identifyThreadMethod();
                        }
                    }
                } 
    
    
            }
    
        }
    
    
    
    
    public Employee getEmployee(String id) {
    
            if(db == null) {
                db = this.getReadableDatabase();
            }
    
            String selectQuery = "SELECT  * FROM " + TABLE_EMPLOYEE + " WHERE "
                    + KEY_ID + "='" + id + "' AND " + KEY_IS_DELETED + "= 0";
    
            //getting stackoverflow error on bellow mentioned line
    
            Cursor cursor = db.rawQuery(selectQuery, null);
    
            if (cursor != null)
                cursor.moveToFirst();
    
            if (cursor.getCount() > 0) {
                Employee employee = new Employee();
                employee.setId(cursor.getString(1));
    
    
                HashMap<Integer, String> templates = new HashMap<>();
                templates.put(1, cursor.getString(2));
                templates.put(2, cursor.getString(3));
                templates.put(3, cursor.getString(4));
                templates.put(4, cursor.getString(5));
                templates.put(5, cursor.getString(6));
                templates.put(6, cursor.getString(7));
                templates.put(7, cursor.getString(8));
                templates.put(8, cursor.getString(9));
                templates.put(9, cursor.getString(10));
                templates.put(10, cursor.getString(11));
    
                employee.setTemplateMap(templates);
                employee.setFirstName(cursor.getString(12));
                employee.setLastName(cursor.getString(13));
                employee.setEmpLevel(cursor.getString(14));
                employee.setEmpIndex(cursor.getInt(15));
                employee.setEmpPIN(cursor.getString(16));
                employee.setEmpAccessMode(cursor.getInt(17));
    
                employee.setEmpEnrollFlag(cursor.getInt(18));
                employee.setAuthMode(cursor.getInt(19));
                employee.setIsDeleted(cursor.getInt(20));
    
                return employee;
            }
            return null;
        }
    

    错误日志

    E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
                      java.lang.StackOverflowError
                          at java.util.WeakHashMap.poll(WeakHashMap.java:569)
                          at java.util.WeakHashMap.put(WeakHashMap.java:608)
                          at android.database.sqlite.SQLiteConnectionPool.finishAcquireConnectionLocked(SQLiteConnectionPool.java:911)
                          at android.database.sqlite.SQLiteConnectionPool.tryAcquirePrimaryConnectionLocked(SQLiteConnectionPool.java:847)
                          at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:613)
                          at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348)
                          at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)
                          at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:586)
                          at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                          at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                          at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                          at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
                          at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
                          at com.cms.attendance.fingerprintreader.database.DatabaseHandler.getEmployee(DatabaseHandler.java:434)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:876)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                          at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThreadMethod(DashboardActivity.java:999)
                        at com.cms.attendance.fingerprintreader.newui.DashboardActivity.identifyThrea
    
    3 回复  |  直到 7 年前
        1
  •  0
  •   Inkognito    7 年前
    if (retvalue != -11) { // reader database not empty
                        if (!flag) {
                            identifyThreadMethod();
                        }
                    }
    

    似乎总是满足此条件,因此identifyThreadMethod();始终称为递归。

        2
  •  0
  •   MikeT    7 年前

    我建议进行以下更改,以基本上满足光标在完成时关闭的需要。

    但不确定这是否是问题所在。

    • P、 该代码原则上是在美国编写的,尚未经过测试,因此可能会有错误。

    :-

    public Employee getEmployee(String id) {
    
            Employee employee; //<<<< Move here to allow cursor close before return.
            if(db == null) {
                db = this.getReadableDatabase();
            }
    
            String selectQuery = "SELECT  * FROM " + TABLE_EMPLOYEE + " WHERE "
                    + KEY_ID + "='" + id + "' AND " + KEY_IS_DELETED + "= 0";
    
            //getting stackoverflow error on bellow mentioned line
            Cursor cursor = db.rawQuery(selectQuery, null);
    
            if (cursor.moveToFirst()) { //<<<< Null is a useless check, `moveToFirst` makes `getCount` check redundant.
    
                employee = new Employee();
                employee.setId(cursor.getString(1));
    
                HashMap<Integer, String> templates = new HashMap<>();
                templates.put(1, cursor.getString(2));
                templates.put(2, cursor.getString(3));
                templates.put(3, cursor.getString(4));
                templates.put(4, cursor.getString(5));
                templates.put(5, cursor.getString(6));
                templates.put(6, cursor.getString(7));
                templates.put(7, cursor.getString(8));
                templates.put(8, cursor.getString(9));
                templates.put(9, cursor.getString(10));
                templates.put(10, cursor.getString(11));
    
                employee.setTemplateMap(templates);
                employee.setFirstName(cursor.getString(12));
                employee.setLastName(cursor.getString(13));
                employee.setEmpLevel(cursor.getString(14));
                employee.setEmpIndex(cursor.getInt(15));
                employee.setEmpPIN(cursor.getString(16));
                employee.setEmpAccessMode(cursor.getInt(17));
    
                employee.setEmpEnrollFlag(cursor.getInt(18));
                employee.setAuthMode(cursor.getInt(19));
                employee.setIsDeleted(cursor.getInt(20));
            }
            cursor.close; //<<<< should always close cursors, could be issue.
            return employee; //<<<< will return null if no rows 
        }
    
        3
  •  0
  •   Tushar Thakur    7 年前

    有关StackOverflower错误的更多信息,请阅读以下答案 https://stackoverflow.com/a/214758/2290580

    我需要全天候运行我的应用程序 identifyThreadMethod() 递归地,所以堆栈大小在增加。 为了解决这个问题,我返回了调用该方法所需的条件,以便完成方法的执行。

    Thread commandThread = (new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        boolean start = true;
                        while(start) {
                            start = identifyThreadMethod();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }));