In CurrentUserRepo -> getLoggedInUser() -> causing crash

Caused by android.database.CursorWindowAllocationException

Cursor window allocation of 4194304 bytes failed. # Open Cursors=421 (# cursors opened by this proc=421)

com.cometchat.pro.repo.CurrentUserRepo.getCurrentUser
com.cometchat.pro.repo.CurrentUserRepo.getCurrentUser (CurrentUserRepo.java:111)
com.cometchat.pro.core.ApiConnection.getDefaultHeaders (ApiConnection.java:1104)
com.cometchat.pro.core.ApiConnection.getGroupConversations (ApiConnection.java:685)
com.cometchat.pro.core.CometChat.getGroupConversations (CometChat.java:2763)
com.cometchat.pro.core.MessagesRequest.fetchMessagesForGroup (MessagesRequest.java:199)
com.cometchat.pro.core.MessagesRequest.fetchPrevious (MessagesRequest.java:92)
com…ChatScreenFragment.fetchMessage (ChatScreenFragment.kt:945)
com…ChatScreenFragment.onResume (ChatScreenFragment.kt:333)

In CurrentUserRepo -> getLoggedInUser() function -> the cursor is not closed.
That is causing the problem when called multiple times.

Hello @kiran_shrestha

Can you please let us know which version of the CometChat Android SDK you are using?

Warm Regards,

CometChat Pro
Mayur Bhandari

I am using
-> implementation ‘com.cometchat:pro-android-chat-sdk:2.1.0’

Now I changed it to 2.1.6 .

Can you please update me on it.

Hello Team,

Can you please provide some update on this.

Hello @kiran_shrestha ,
Can you please share the code snippet in your codebase that is leading to this crash. This will help me investigate better.

Function called on resume of the fragment. →

private fun getUnreadGrpMessageCount() {

    try {
        CometChat.getUnreadMessageCountForAllGroups(true, object :
            CometChat.CallbackListener<HashMap<String?, Int?>?>() {
            override fun onSuccess(stringIntegerHashMap: HashMap<String?, Int?>?) {
                juiceActivityViewModel.grpChatList.forEach { groupChat ->
                    run {
                        val matchingGuids =
                            stringIntegerHashMap?.keys?.filter { gUID -> groupChat.groupId == gUID }

                        if (matchingGuids?.size ?: 0 > 0) {
                            val matchingGuid = matchingGuids?.get(0)
                            if (matchingGuid != null) {
                                groupChat.unReadMessageCount =
                                    stringIntegerHashMap?.get(matchingGuid)
                            }
                        } else {
                            groupChat.unReadMessageCount = 0
                        }


                    }
                }
                channelAdapter.refreshAdapter(
                    juiceActivityViewModel.grpChatList,
                    juiceActivityViewModel.selectedChannelId
                )

            }

            override fun onError(e: CometChatException?) {
                Timber.e(e)
            }
        })

    } catch (e: Exception) {
        Timber.e(e)
    }
}

Error Log->

Fatal Exception: java.lang.RuntimeException
Unable to resume activity {com.example.exampleApp/com.example.exampleApp.view.juice.JuiceActivity}: android.database.CursorWindowAllocationException: Cursor window allocation of 4194304 bytes failed. # Open Cursors=454 (# cursors opened by this proc=454)
android.app.ActivityThread.performResumeActivity (ActivityThread.java:4053)
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:4085)
android.app.servertransaction.ResumeActivityItem.execute (ResumeActivityItem.java:51)
android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:145)
android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:70)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1984)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loop (Looper.java:216)
android.app.ActivityThread.main (ActivityThread.java:7211)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)
Caused by android.database.CursorWindowAllocationException
Cursor window allocation of 4194304 bytes failed. # Open Cursors=454 (# cursors opened by this proc=454)
android.database.CursorWindow. (CursorWindow.java:142)
android.database.sqlite.SQLiteCursor.clearOrCreateWindow (SQLiteCursor.java:315)
android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:155)
android.database.sqlite.SQLiteCursor.getCount (SQLiteCursor.java:149)
android.database.AbstractCursor.moveToPosition (AbstractCursor.java:220)
android.database.AbstractCursor.moveToFirst (AbstractCursor.java:259)
com.cometchat.pro.repo.CurrentUserRepo.getCurrentUser (CurrentUserRepo.java:111)
com.cometchat.pro.core.ApiConnection.getDefaultHeaders (ApiConnection.java:1104)
com.cometchat.pro.core.ApiConnection.getGroupConversations (ApiConnection.java:685)
com.cometchat.pro.core.CometChat.getGroupConversations (CometChat.java:2763)
com.cometchat.pro.core.MessagesRequest.fetchMessagesForGroup (MessagesRequest.java:199)
com.cometchat.pro.core.MessagesRequest.fetchPrevious (MessagesRequest.java:92)
com.example.exampleApp.view.juice.ChatScreenFragment.fetchMessage (ChatScreenFragment.kt:945)
com.example.exampleApp.view.juice.ChatScreenFragment.onResume (ChatScreenFragment.kt:333)
androidx.fragment.app.Fragment.performResume (Fragment.java:2748)
androidx.fragment.app.FragmentStateManager.resume (FragmentStateManager.java:373)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1211)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1368)
androidx.fragment.app.FragmentManager.moveFragmentToExpectedState (FragmentManager.java:1446)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1509)
androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:2637)
androidx.fragment.app.FragmentManager.dispatchResume (FragmentManager.java:2601)
androidx.fragment.app.Fragment.performResume (Fragment.java:2757)
androidx.fragment.app.FragmentStateManager.resume (FragmentStateManager.java:373)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1211)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1368)
androidx.fragment.app.FragmentManager.moveFragmentToExpectedState (FragmentManager.java:1446)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1509)
androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:2637)
androidx.fragment.app.FragmentManager.dispatchResume (FragmentManager.java:2601)
androidx.fragment.app.FragmentController.dispatchResume (FragmentController.java:269)
androidx.fragment.app.FragmentActivity.onResumeFragments (FragmentActivity.java:478)
androidx.fragment.app.FragmentActivity.onPostResume (FragmentActivity.java:467)
androidx.appcompat.app.AppCompatActivity.onPostResume (AppCompatActivity.java:204)
android.app.Activity.performResume (Activity.java:7649)
android.app.ActivityThread.performResumeActivity (ActivityThread.java:4045)
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:4085)
android.app.servertransaction.ResumeActivityItem.execute (ResumeActivityItem.java:51)
android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:145)
android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:70)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1984)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loop (Looper.java:216)
android.app.ActivityThread.main (ActivityThread.java:7211)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)

I also gone through the file “CurrentUserRepo” → getCurrentUser function.

public static CurrentUser getCurrentUser() {
CurrentUser user = null;

    try {
        SQLiteDatabase db = SQLiteManager.getInstance().openDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM CurrentUser WHERE uid LIKE '" + PreferenceHelper.getLoggedInUID() + "'", (String[])null);
        if (cursor != null && cursor.moveToFirst()) {
            cursor.moveToFirst();
            user = new CurrentUser();
            user.setUid(cursor.getString(0));
            user.setName(cursor.getString(1));
            user.setAvatar(cursor.getString(3));
            user.setLink(cursor.getString(4));
            user.setRole(cursor.getString(5));
            if (cursor.getString(6) != null) {
                user.setMetadata(new JSONObject(cursor.getString(6)));
            }

            user.setStatus(cursor.getString(8));
            user.setStatusMessage(cursor.getString(9));
            user.setLastActiveAt(cursor.getLong(10));
            user.setIdentity(cursor.getString(11));
            user.setSecret(cursor.getString(12));
            user.setAuthToken(cursor.getString(13));
            user.setJwt(cursor.getString(14));
            String tagsArray = cursor.getString(15);
            if (tagsArray != null) {
                JSONArray tags = new JSONArray(tagsArray);
                List<String> tagsList = new ArrayList();

                for(int i = 0; i < tags.length(); ++i) {
                    tagsList.add(tags.getString(i));
                }

                user.setTags(tagsList);
            }
        }

        SQLiteManager.getInstance().closeDatabase();
    } catch (JSONException var7) {
        Logger.error("Error getting users from local database : " + var7.getMessage());
    }

    return user;
}

Here the cursor used is not closed anywhere and is being called multiple times.
I debugged the code placing the breakpoint on getCurrentUser() which is being called 30-40 times in debug build and is continuously called in some intervals.

Hello @kiran_shrestha
I will add a fix and release a beta version by tomorrow end of the day. I Will share the beta version with you by tomorrow end of the day. You can check with the version and let us know if the issue is resolved. Once you confirm, we will release a stable version with the fix.

Hope this helps.

Hello @kiran_shrestha
We have released a new version of the Android SDK (2.1.7-beta3). Please upgrade to the latest version and provide us with your feedback.

Thanks

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.