Hi I need to store array of Bitmaps in Room database like
@ColumnInfo(name = "imageList")
var imageList: ArrayList<Bitmap>
but I couldn't do it right way because of my converter I think.it only puts first element in bitmap list. How can I solve that?
class BitmapListConverter {
@TypeConverter
fun toBitmapList(bitmap: Bitmap): ArrayList<Bitmap> {
return arrayListOf(bitmap)
}
@TypeConverter
fun fromBitmapList(array:ArrayList<Bitmap>): Bitmap {
val bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
return if (array.isEmpty()) bmp else array.first() //this causing issue
}
}
With SQLite and therefore Room a column can contain just 1 item of data. A Type converter must convert from whatever to a single unit of data that can be an integer type value (INTEGER type in SQLite), a decimal type value (REAL type), a null (useless unless indicating no data), a stream of characters (TEXT type) or a stream of bytes (BLOB).
Null, INTEGER and REAL types are probably of little use for storing a list of something.
You are expecting many bitmaps to be saved as a single BITMAP but are only getting the first. If you could append the bitmaps into many bitmaps then that would work. Perhaps some bitmap handling libraries/utilities could accomplish this. However, you would then also need to dismantle/split the single bitmap into many. This would probably be quite some task as it is not very likely that a bitmap can hold the additional information needed to dismantle the many bitmaps.
What I would suggest is to have a table (an
@Entityannotated class) in which a single bitmap is stored per row. A bitmap can then be a child to the parent table and you would have a POJO class that would have the parent (@Entityannotated class) field annotated with@Embeddedand the ArrayList field annotated with@Relation.A decision would have to be made as to the type of relationship. It could be a 1 parent with many children, in which case the child
@Entity(the bitmap) could have a field to uniquely identify the parent of the child.The alternative could be to have a many-many relationship where a single bitmap could have many parents and many parents could be related to many children (bitmaps). Such a relationship is accomplished by having a third table that has two core columns/fields; one for the unique identifier of the parent; the other for the unique identifier of the bitmap. The two columns combined would form the primary key (noting that the
primaryKeyparameter of the@Entityannotation has to be used to specify this composite primary key).For this many-many relationship
@Relationannotation in the POJO differ in that it would include theassociateByparameter to specify theJunction(the name of columns in the third table that uniquely identify the parent and the child).Demo
The following demonstrates both a 1-many and a many-many method.
It should be noted that the bitmap handling has been simplified, but that a type converters were required. They too are very simple but importantly just a single bitmap is stored.
The complication is that both methods have been included.
The Code
First the Parent that itself DOES NOT include the troublesome List (ArrayList):-
Next the Entity for storing a single bitmap per row for the the 1-Many version. i.e. it's parent is stored and thus a bitmap can only have the 1 parent:-
To combine the Parent with the child bitmaps the POJO :-
*For the Many-Many version
The entity for storing single bitmaps:-
The third (associative/mapping and other names .... table):-
To combine the Parent with the child bitmaps the POJO with the extended associateBy parameter:-
The Type Converter class with the from and to converters (very simple just to demonstrate):-
The
@Daointerface that allows data to be inserted and extracted (as parent with the list of bitmaps for each version/method):-A simple
@Databaseannotated abstract class. Noting that for brevity the main thread has been opened up for use:-@TypeConverts*PLURAL annotation to provide the fullest scope of the Type Converters.Finally some activity code to actually demonstrate inserting and extracting data replicating the parent/child for each method/version:-
Results
The log includes:-
For the 1-many method:-
For the many-many method:-
....Bitmap@???????is different as it's the objects memory location NOT THE ACTUAL BITMAP DATA (i.e. part of the simplicity of the demo).Using App Inspection:-
Doing it as per the Question
Instead of storing the bitmaps directly as bitmaps they could be stored as a JSON representation of the ArrayList. This would require utilising a Gson library for the type conversion. The JSON represents the objects as a string and thus adds bloat.
Again a simple demo.
First a class for the BitMap arrayList (just a POJO that is included in the Entity):-
And now the Entity;-
2 Type Converter functions:-
Some additional
@Daofunctions:-The amended
@Databaseannotation to include the additional table/entity:-Finally some extra activity code:-
The result being:-
The table, via App Inspection:-
"mNativePtr":3865181248is a compressed form of the 100 * 100 bitmap.Note
Although SQLite can be quite effective and efficient at storing large amounts of contiguous data. Storing such data, especially on Android devices can be very inefficient due to the underlying API and available resources. Storing images is typically frowned upon rather it is frequently advised that the images be stored as files and that the path or part thereof is stored in the database.