MobileFirst Platform JSONStore 从数据库读取时出错

MobileFirst Platform JSONStore An error occurred when reading from the database

IBM MobileFirst 版本:6.3 手机 OS:Android 4.4.4

我有一个用例,我们需要将单个或多个 base64 编码的图像字符串存储在集合内的单个文档中。 (由于用例的性质,无法将图像拆分为集合中的多个文档)

将最多 7 个 base64 编码的图像字符串存储到同一个文档中可以正常工作。 (包含 7 个 base64 字符串图像的文档已添加到 JSONStore)。 将包含 8 个 base64 编码字符串图像的文档添加到集合中的同一文档时。文档已成功添加到集合中。但是当在集合上调用 findAll() 时(它只包含 1 个文档和 8 个 base64 编码的图像;在这个用例中,需要一个 findAll() 因为填充搜索字段的数据在数据时不存在从集合中获取);发生以下错误:

Java:

E/JSONSTORE(24451): JSONStoreLogger.logError in JSONStoreLogger.java:189 :: Error when attempting to find a document. An error occurred when reading from the database.
E/JSONSTORE(24451): com.worklight.jsonstore.exceptions.JSONStoreFindException: Error when attempting to find a document. An error occurred when reading from the database.
E/JSONSTORE(24451):     at com.worklight.jsonstore.api.JSONStoreCollection.findDocuments(JSONStoreCollection.java:896)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.FindActionDispatcher.databaseActionDispatch(FindActionDispatcher.java:117)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.BaseDatabaseActionDispatcher.actionDispatch(BaseDatabaseActionDispatcher.java:36)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.BaseActionDispatcher.dispatch(BaseActionDispatcher.java:90)
E/JSONSTORE(24451):     at com.worklight.androidgap.plugin.DispatchingPlugin$ActionDispatcherRunnable.run(DispatchingPlugin.java:79)
E/JSONSTORE(24451):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/JSONSTORE(24451):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/JSONSTORE(24451):     at java.lang.Thread.run(Thread.java:841)
E/JSONSTORE(24451): Caused by: java.lang.IllegalStateException: get field slot from row 0 col 0 failed
E/JSONSTORE(24451):     at net.sqlcipher.CursorWindow.getLong_native(Native Method)
E/JSONSTORE(24451):     at net.sqlcipher.CursorWindow.getLong(CursorWindow.java:381)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:110)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractCursor.moveToPosition(AbstractCursor.java:195)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractCursor.moveToNext(AbstractCursor.java:257)
E/JSONSTORE(24451):     at android.database.CursorWrapper.moveToNext(CursorWrapper.java:166)
E/JSONSTORE(24451):     at com.worklight.jsonstore.api.JSONStoreCollection.findDocuments(JSONStoreCollection.java:877)
E/JSONSTORE(24451):     ... 7 more
E/JSONSTORE(24451): JSONStoreLogger.logError in JSONStoreLogger.java:189 :: error while executing find query on database "tempCollection"com.worklight.jsonstore.exceptions.JSONStoreFindException: Error when attempting to find a document. An error occurred when reading from the database.
E/JSONSTORE(24451): com.worklight.jsonstore.exceptions.JSONStoreFindException: Error when attempting to find a document. An error occurred when reading from the database.
E/JSONSTORE(24451):     at com.worklight.jsonstore.api.JSONStoreCollection.findDocuments(JSONStoreCollection.java:896)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.FindActionDispatcher.databaseActionDispatch(FindActionDispatcher.java:117)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.BaseDatabaseActionDispatcher.actionDispatch(BaseDatabaseActionDispatcher.java:36)
E/JSONSTORE(24451):     at com.worklight.androidgap.jsonstore.dispatchers.BaseActionDispatcher.dispatch(BaseActionDispatcher.java:90)
E/JSONSTORE(24451):     at com.worklight.androidgap.plugin.DispatchingPlugin$ActionDispatcherRunnable.run(DispatchingPlugin.java:79)
E/JSONSTORE(24451):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/JSONSTORE(24451):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/JSONSTORE(24451):     at java.lang.Thread.run(Thread.java:841)
E/JSONSTORE(24451): Caused by: java.lang.IllegalStateException: get field slot from row 0 col 0 failed
E/JSONSTORE(24451):     at net.sqlcipher.CursorWindow.getLong_native(Native Method)
E/JSONSTORE(24451):     at net.sqlcipher.CursorWindow.getLong(CursorWindow.java:381)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:110)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractCursor.moveToPosition(AbstractCursor.java:195)
E/JSONSTORE(24451):     at net.sqlcipher.AbstractCursor.moveToNext(AbstractCursor.java:257)
E/JSONSTORE(24451):     at android.database.CursorWrapper.moveToNext(CursorWrapper.java:166)
E/JSONSTORE(24451):     at com.worklight.jsonstore.api.JSONStoreCollection.findDocuments(JSONStoreCollection.java:877)
E/JSONSTORE(24451):     ... 7 more
E/wl.jsonstore(24451): {"src":"find","err":22,"msg":"INVALID_SEARCH_FIELD","col":"tempCollection","usr":"testUser","doc":{},"res":{}}

Java脚本:

{"src":"findAll","err":22,"msg":"INVALID_SEARCH_FIELD","col":"tempCollection","usr":"testUser","doc":{},"res":{}}

是我做错了什么,还是我使用不当?

编辑:

初始化:

var storeDetails = {
    collections: {
        tempCollection: {}
    },
    options: {
        username: 'ausername',
        password: 'apassword',
        localKeyGen: true //Optional local key generation flag, default false.
    }
};

WL.JSONStore.init(storeDetails.collections, storeDetails.options);

查找全部:

var options = {
    limit: 1
};
WL.JSONStore.get('tempCollection').findAll(options);

Base64 编码的图像字符串: 我正在使用 Cordova 相机 API(包含在 Worklight/MF 中)。 代码片段: 通过使用 Camera.DestinationType.DATA_URL,图像以 base64 编码的字符串形式返回。

var options = {
    quality: 100,
    destinationType: Camera.DestinationType.DATA_URL,
    sourceType: Camera.PictureSourceType.CAMERA,
    allowEdit: true,
    encodingType: Camera.EncodingType.PNG,
    targetWidth: 500,
    targetHeight: 500,
    popoverOptions: CameraPopoverOptions,
    saveToPhotoAlbum: true,
    cameraDirection: Camera.Direction.BACK
};

navigator.camera.getPicture(function (imageData) {
    var doc = {
        src: imageData;
    };
    WL.JSONStore.get('tempCollection').add(doc);
}, function (err) {

}, options);

我能够重现您的问题。在 JSON 文档中添加一些图像作为单个数组的一部分后,我遇到了与您提供的相同的错误。而且,在你显示的错误之前,我可以看到另一个

05-04 20:27:38.934: E/CursorWindow(32148): need to grow: mSize = 1048576, size = 1107180, freeSpace() = 1048482, numRows = 1
05-04 20:27:38.934: E/CursorWindow(32148): Attempting to grow window beyond max size (1048576)
05-04 20:27:38.934: E/Cursor(32148): Failed allocating 1107180 bytes for text/blob at 0,1
05-04 20:27:38.935: D/Cursor(32148): finish_program_and_get_row_count row 0
05-04 20:27:39.151: E/CursorWindow(32148): need to grow: mSize = 1048576, size = 1107180, freeSpace() = 1048482, numRows = 1
05-04 20:27:39.151: E/CursorWindow(32148): Attempting to grow window beyond max size (1048576)
05-04 20:27:39.151: E/Cursor(32148): Failed allocating 1107180 bytes for text/blob at 0,1
05-04 20:27:39.152: D/Cursor(32148): finish_program_and_get_row_count row 0
05-04 20:27:39.152: E/CursorWindow(32148): Bad request for field slot 0,0. numRows = 0, numColumns = 2

所以我的猜测是您强调了设备内存的限制。

当您将多张图片添加到单个 JSON 文档时,您正在创建一个巨大的 JSON 文档。然后当你搜索它时,可能有一些类型的解析操作,或者类似的东西,需要在内存中分配整个 JSON 。 findAll 本身的结果将包含那个巨大的 json 文档。并且可能需要使用连续内存分配。

问题是单个 Android 应用可用的内存总量是有限的。实际值取决于设备制造商。而且它不一定与 "high-end" 设备的性能或设备中可用的总内存有关。一些制造商可能会创建具有 2GB 内存的设备,但每个应用程序只有几 MB 可用,因此他们优先考虑保持许多应用程序 运行 并行的能力,而不是几个应用程序占用所有资源。

最后,我的建议是您真的应该将每个图像存储在一个独立的 JSON 文档中。您可以拥有一个包含 ID 数组的文档和存储在第二个集合中的图像,或者其他一些替代解决方案。

另请注意,这不是 JSON 商店的限制,而是 Android 平台施加的限制。永远不会允许单个应用程序单独消耗所有内存资源,它总是限制在一些 MB。