IBM MobileFirst version: 6.3 Mobile OS: Android 4.4.4
IBM MobileFirst版本:6.3移动操作系统:Android 4.4.4
I have a use-case where we need to store a single or multiple base64-encoded image string(s) in a single document inside a collection. (Due to the nature of the use-case, it is not possible to split the images into multiple documents inside a collection)
我有一个用例,我们需要在一个集合中的单个文档中存储一个或多个base64编码的图像字符串。 (由于用例的性质,无法将图像拆分为集合中的多个文档)
Storing up to 7 base64-encoded image string into the same document works as intended. (A document with 7 base64 string images is added to the JSONStore). When a document with 8 base64-encoded string images has been added to the same document inside a collection. The document is successfully added to the collection. But when a findAll() is called on the collection (it only holds 1 document with 8 base64-encoded images; in this use case a findAll() is needed becasue there the data to populate a searchfield is not present at the time the data is fetched from the Collection); the following errors occure:
将最多7个base64编码的图像字符串存储到同一文档中可以按预期工作。 (具有7个base64字符串图像的文档被添加到JSONStore)。将具有8个base64编码的字符串图像的文档添加到集合内的同一文档中时。该文档已成功添加到集合中。但是当在集合上调用findAll()时(它只包含1个带有8个base64编码图像的文档;在这个用例中需要一个findAll(),因为在数据时不存在填充搜索字段的数据从Collection中取出);发生以下错误:
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":{}}
Javascript:
{"src":"findAll","err":22,"msg":"INVALID_SEARCH_FIELD","col":"tempCollection","usr":"testUser","doc":{},"res":{}}
Is there something I'm doing wrong, or something I am misusing?
有什么我做错了,或者我在滥用的东西?
EDIT:
init:
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);
findAll:
var options = {
limit: 1
};
WL.JSONStore.get('tempCollection').findAll(options);
Base64-encoded image string: I am using the Cordova camera API (included with Worklight/MF). A snippet of the code: By using Camera.DestinationType.DATA_URL, the image is returned as a base64-encoded string.
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);
1 个解决方案
#1
I was able to reproduce your problem. After adding some images as part of a single array in a JSON doc I got the same error that you presented. But also, before the error you showed I can see this other one
我能够重现你的问题。在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
So my guess is that you are stressing the limits of your device memory.
所以我猜你是在强调设备内存的极限。
When you add several pictures to a single JSON document you are creating a huge JSON document. Then when you search it, probably there is some type o parsing operation, or something similar, that requires the entire JSON to be allocated in memory. The result of findAll itself will contain that huge json document. And possibly that need to use continuous memory allocation.
将几张图片添加到单个JSON文档时,您将创建一个巨大的JSON文档。然后当你搜索它时,可能会有一些类型的解析操作,或类似的东西,需要在内存中分配整个JSON。 findAll本身的结果将包含那个巨大的json文档。并且可能需要使用连续内存分配。
The problem is that the total amount of memory available to a single Android app is limited. The actual value depends on the device manufacturer. And it is not necessarily related to how "high-end" the device is, or total memory available in the device. Some manufactures may create devices with 2GB of memory but only a few MB available for each app, so they are prioritizing the ability to keep many apps running in parallel instead of a few apps taking all the resources.
问题是单个Android应用程序可用的内存总量是有限的。实际值取决于设备制造商。并不一定与设备的“高端”或设备的总内存有关。一些制造商可能会创建具有2GB内存但每个应用程序只有几MB的设备,因此他们优先考虑保持许多应用程序并行运行的能力,而不是少数应用程序获取所有资源。
In the end, my suggestion is that you really should store each image in an independent JSON document. You could have a single document with an array of IDs and the images stored in a second collection, or some other alternative solution.
最后,我的建议是你真的应该将每个图像存储在一个独立的JSON文档中。您可以拥有一个包含ID数组的文档,以及存储在第二个集合中的图像,或其他一些替代解决方案。
Also note that this is NOT a limitation of JSONStore, but a limitation imposed by Android platform. A single app will never be allowed to consume all the memory resources alone, it is always limited to some MB.
另请注意,这不是JSONStore的限制,而是Android平台强加的限制。永远不会允许单个应用程序单独使用所有内存资源,它始终限制为某些MB。
#1
I was able to reproduce your problem. After adding some images as part of a single array in a JSON doc I got the same error that you presented. But also, before the error you showed I can see this other one
我能够重现你的问题。在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
So my guess is that you are stressing the limits of your device memory.
所以我猜你是在强调设备内存的极限。
When you add several pictures to a single JSON document you are creating a huge JSON document. Then when you search it, probably there is some type o parsing operation, or something similar, that requires the entire JSON to be allocated in memory. The result of findAll itself will contain that huge json document. And possibly that need to use continuous memory allocation.
将几张图片添加到单个JSON文档时,您将创建一个巨大的JSON文档。然后当你搜索它时,可能会有一些类型的解析操作,或类似的东西,需要在内存中分配整个JSON。 findAll本身的结果将包含那个巨大的json文档。并且可能需要使用连续内存分配。
The problem is that the total amount of memory available to a single Android app is limited. The actual value depends on the device manufacturer. And it is not necessarily related to how "high-end" the device is, or total memory available in the device. Some manufactures may create devices with 2GB of memory but only a few MB available for each app, so they are prioritizing the ability to keep many apps running in parallel instead of a few apps taking all the resources.
问题是单个Android应用程序可用的内存总量是有限的。实际值取决于设备制造商。并不一定与设备的“高端”或设备的总内存有关。一些制造商可能会创建具有2GB内存但每个应用程序只有几MB的设备,因此他们优先考虑保持许多应用程序并行运行的能力,而不是少数应用程序获取所有资源。
In the end, my suggestion is that you really should store each image in an independent JSON document. You could have a single document with an array of IDs and the images stored in a second collection, or some other alternative solution.
最后,我的建议是你真的应该将每个图像存储在一个独立的JSON文档中。您可以拥有一个包含ID数组的文档,以及存储在第二个集合中的图像,或其他一些替代解决方案。
Also note that this is NOT a limitation of JSONStore, but a limitation imposed by Android platform. A single app will never be allowed to consume all the memory resources alone, it is always limited to some MB.
另请注意,这不是JSONStore的限制,而是Android平台强加的限制。永远不会允许单个应用程序单独使用所有内存资源,它始终限制为某些MB。