android.database.CursorWindowAllocationException:2048 kb的游标窗口分配失败。 #Open Cursors = 971(此proc = 971打开的#游标)

时间:2017-08-30 07:22:01

标签: java android database multithreading sqlite

  

android.database.CursorWindowAllocationException:2048 kb的游标窗口分配失败。 #Open Cursors = 971(此proc = 971打开的#游标)

您好我有一个用于查询数据库的控制器。用于异步获取数据的代码,因为我有超过1000条记录。

public void query(final Uri contentUri,
                  final String where,
                  final String[] selectionArgs,
                  final String sortOrder,
                  final int from,
                  final int limit,
                  final AdvancedQueryListener<Cursor> listener) {
    if (listener == null)
        return;
    if (null == SamsungApp.getAppContext())
        return;
    final ContentResolver mContentResolver = SamsungApp.getAppContext().getContentResolver();
    final Handler mHandler = Utility.instantiateHandler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what) {
                case 1:
                    Cursor cursor = (Cursor) message.obj;
                    listener.onGetResult(cursor);
            }
            return false;
        }
    });

    Runnable queryRunner = new Runnable() {
        @Override
        public void run() {
            StringBuilder sqlStatement = null;

            if (!TextUtils.isEmpty(sortOrder)) {
                if (sqlStatement == null)
                    sqlStatement = new StringBuilder();
                sqlStatement.append(sortOrder);
            }

            if (limit > 0) {
                if (sqlStatement == null)
                    sqlStatement = new StringBuilder();
                sqlStatement.append(" LIMIT ");
                sqlStatement.append(limit);
            }

            if (from > 0) {
                if (sqlStatement == null)
                    sqlStatement = new StringBuilder();
                sqlStatement.append(" OFFSET ");
                sqlStatement.append(from);
            }
            Cursor cursor = mContentResolver.query(contentUri, null, where, selectionArgs, sqlStatement.toString());
            Message message = mHandler.obtainMessage(1);
            message.obj = cursor;
            mHandler.sendMessage(message);
        }
    };

    FixedThreadPoolExecutor.execute(queryRunner);
}
  

我创建了一个Fixed线程池来处理我的应用程序中的所有线程。在那里,我创建了具有最多100个并发任务的Threadpool执行器;

    FixedThreadPoolExecutor executor = getInstance();
    executor.mThreadPoolExecutor.execute(runnable);
  

我的内容提供商在下面给出

public boolean close() {
    if (this.isActive) {
        mAppDbHelper.removeConnection();
    }
    int count = mAppDbHelper.getCounter();
    if (count == 0) {
        synchronized (mutex) {
            if (mSqldb.inTransaction()) mSqldb.endTransaction();
            if (mSqldb.isOpen()) mSqldb.close();
            mSqldb = null;
        }
    }
    return (count == 0);
}


public SQLiteDatabase open() {
    if (!this.isActive) {
        mAppDbHelper.addConnection();
    }
    if (mSqldb == null || !mSqldb.isOpen()) {
        synchronized (mutex) {
            mSqldb = mAppDbHelper.getWritableDatabase();
        }
    }
    this.isActive = true;
    return mSqldb;
}

// 
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    final SQLiteDatabase db = open();
    Cursor cursor = null;
    if (db != null) {
        /* SQLiteQueryBuilder helps to construct queries that are more complex than
         * those supported by the SQLiteDatabase functions (for example, sub queries).
         */
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(uri.getLastPathSegment()); // Extract table name fromDeviceCursor uri
        cursor = queryBuilder.query(db,
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder
        );
        if (cursor != null) {
            cursor.setNotificationUri(getContext().getContentResolver(), uri);
        }
    } else {
        throw new DataLayerException(DEBUG_TAG + "SQLiteDatabase is null");
    }
    return cursor;
}
  

我的问题是每次如果同时查询我就会遇到问题

FATAL EXCEPTION: main
                                 Process: com.samsung.lighting, PID: 4949
                                 android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
                                     at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
                                     at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:843)
                                     at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
                                     at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
                                     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
                                     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
                                     at android.content.ContentResolver.query(ContentResolver.java:512)
                                     at android.content.ContentResolver.query(ContentResolver.java:435)
                                     at com.samsung.lighting.storage.repository.impl.WiSeGalleryRepositaryImpl.getNonSyncedIcon(WiSeGalleryRepositaryImpl.java:278)
                                     at com.samsung.lighting.sync.OfflineSyncManager.syncAddedIcons(OfflineSyncManager.java:194)
                                     at com.samsung.lighting.sync.OfflineSyncManager.startSyncing(OfflineSyncManager.java:164)
                                     at com.samsung.lighting.sync.OfflineSyncManager.onFailure(OfflineSyncManager.java:737)
                                     at com.wise.cloud.group.WiSeCloudGroupManager$9.onFailure(WiSeCloudGroupManager.java:1603)
                                     at com.wise.cloud.queue.WiSeQueueManagement.addToQueue(WiSeQueueManagement.java:173)
                                     at com.wise.cloud.queue.WiSeQueueManagement.initialCheckInToQueueManagement(WiSeQueueManagement.java:117)
                                     at com.wise.cloud.group.WiSeCloudGroupManager.setLogicalGroupAssociations(WiSeCloudGroupManager.java:1662)
                                     at com.samsung.lighting.cloud_interactor.CloudGroupManager.setGroupAssociations(CloudGroupManager.java:131)
                                     at com.samsung.lighting.sync.OfflineSyncManager$7.onGetResult(OfflineSyncManager.java:391)
                                     at com.samsung.lighting.sync.OfflineSyncManager$7.onGetResult(OfflineSyncManager.java:387)
                                     at com.samsung.lighting.storage.repository.impl.WiSeGroupAssociationRepositoryImpl$1.onGetResult(WiSeGroupAssociationRepositoryImpl.java:344)
                                     at com.samsung.lighting.storage.repository.impl.WiSeGroupAssociationRepositoryImpl$1.onGetResult(WiSeGroupAssociationRepositoryImpl.java:330)
                                     at com.samsung.lighting.storage.repository.SamsungContentResolver$1.handleMessage(SamsungContentResolver.java:73)
                                     at android.os.Handler.dispatchMessage(Handler.java:98)
                                     at android.os.Looper.loop(Looper.java:148)
                                     at android.app.ActivityThread.main(ActivityThread.java:5451)
                                     at java.lang.reflect.Method.invoke(Native Method)
                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

注意 每个人都告诉我关闭光标Cursor.close()喜欢

在我的应用程序的任何地方,我都放入了

try{
    //code 
}finally{
    if(null!=cursor)
        cursor.close
}

帮我找出问题所在。

提前致谢

0 个答案:

没有答案