2

I am reading employee fingerprint using a fingerprint reader. Once morphoDatabase.identify is executed, the fingerprint reader waits for employees fingerprint. After the fingerprint is captured I get employeeId from fingerprint reader database. Now I want to get this employee details from my sqlite database and show greeting message. After this I start the identification process all over again.

Issue: When my identification count reaches somewhere about 100, my app is crashing.

I have added logcat error.

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;
    }

Error log

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
Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
Tushar Thakur
  • 956
  • 3
  • 15
  • 32

3 Answers3

0
if (retvalue != -11) { // reader database not empty
                    if (!flag) {
                        identifyThreadMethod();
                    }
                }

Seems like this condition is always met, therefore identifyThreadMethod(); is always called recursive.

Inkognito
  • 224
  • 1
  • 2
  • 10
  • though this condition always meets, the fingerprint reading operation at least takes 1 to 2 seconds, so the database read is happening every 2 seconds. – Tushar Thakur Apr 04 '18 at 07:13
  • Please explain why do you need to call identifyThreadMethod(); recursive? Whats the logic behind it? – Inkognito Apr 04 '18 at 09:57
  • The app is for employee attendance...so if one employee identifies himself...the identification should restart for next employee in queue – Tushar Thakur Apr 04 '18 at 12:02
0

I'd suggest the following changes, to basically cater for the cursor's being closed when they are done with.

Not sure that this is the issue though.

  • P.S. the code is in-principle and hasn't been tested so may have errors.

:-

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 
    }
MikeT
  • 51,415
  • 16
  • 49
  • 68
0

Please read following answer for more clarity on StackoverflowError https://stackoverflow.com/a/214758/2290580

I need to run my application 24*7 and I was calling identifyThreadMethod() recursively, so stack size was increasing. To solve this issue I returned the condition on which I needed to call the method, so that method execution will be completed.

Thread commandThread = (new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    boolean start = true;
                    while(start) {
                        start = identifyThreadMethod();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }));
Tushar Thakur
  • 956
  • 3
  • 15
  • 32