Storing ArrayList<? extends BaseModel> in Realm - android

I have an ArrayList<? extends BaseModel> that I'd like to store in Realm.
I have several classes that extend BaseModel and they're all stored in this ArrayList. Will Realm just do the right thing if I store this on disk? Each child class may have it's own additional members and methods.
I should probably just try testing this myself, but I'm away from my dev machine, so thought I'd ask anyway and answer it myself if no one gets to it first.
Thank You!

You can store list of BaseModel by call copyToRealmOrUpdate(), if BaseModel extend of RealmObject class or if implement RealmModel interface:
void storeListToRealm(List<? extends BaseModel> models) {
realm.beginTransaction();
realm.copyToRealmOrUpdate(models);
realm.commitTransaction();
}
Otherwise, you need to create "StoreModel", which you can store to realm, and mapping from BaseModel to StoreModel.

Realm generates a RealmModuleMediator class that has the following code:
public String getTableName(Class<? extends RealmModel> clazz) {
checkClass(clazz);
if (clazz.equals(com.yourpackage.somemodel)) {
return io.realm.SomeModelRealmProxy.getTableName();
} else if (clazz.equals(com.yourpackage.anothermodel)) {
return io.realm.AnotherRealmProxy.getTableName();
} else if ...
Looks to me like it makes no difference whether you pass in the subclass or the super class.

Related

Custom adapter of interface object in Android

In my Android Application I've some objects which represent different kinds of operations.
public class OperacionDivisa implements IOperacion {
public class OperacionLargo implements IOperacion {
public class OperacionMedio implements IOperacion {
public class OperacionOpciones implements IOperacion {
Each kind of operation implements IOperation interface so I can make an ArrayList of IOperations and store all operations in a single ArrayList.
Now I'd like to do the inverse process. I want to get the arraylist of operations from Firebase (which has already been achieved) and I'd like to show the operations in a ListView
I created a custom adapter as follows:
public class ListViewAdapterOperaciones extends ArrayAdapter<IOperacion>
The issue is that I need to cast each object to its original class to show in a textview different attributes. So this is not useful.
IOperacion operacion = (IOperacion) getItem(position);
So, for each object I'd like to show some data in the listView but I haven't been able to figure out how to do this. Any help would be appreciated.
Thanks in advance.
Use an if statement (or similar) to check instanceof, then use the objects as the subclass.
if (operacion instanceof OperacionLargo) {
// Large operation
} else if (operacion instanceof OperacionDivisa) {
// Other operation
}

Is it necessary to extend every model class with RealmObject while working with realm?

I am using Realm ORM for my app. I have 3 model classes of which two extends RealmObject while the other one does not.
public class Party extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
public String name;
public String name_en;
public String name_ne;
public String address;
public String phoneNumber;
public String taxRegistrationNumber;
public String partyType;
the second class holds a field of type Party. But this does not extends RealmObject
public class CreatePurchaseOrder implements Parcelable {
public int voucherNumber;
public Date date;
public Party party;
String agent;
The third class holds a field for CreatePurchaseOrder and extends RealmObject
[public class CreatePurchaseOrderRow extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
private int serialNumber;
private String specification;
private float quantity;
private float rate;
private String remarks;
private boolean fulfilled;
private CreatePurchaseOrder createPurchaseOrder;
With this approach it generates an error message
screenshot of error message
So is it necessary to extend every Model class with RealmObject?
Technically you don't have to extend RealmObject directly from your model class.
The docs say:
Realm model classes are created by extending the RealmObject base class.
Which implies that if you don't extend RealmObject, your class is not a Realm model, thus it can't be stored in a realm.
However you can also implement the RealmModel interface and annotate your model class with #RealmClass
#RealmClass
public class MyModel implements RealmModel {
}
as mentioned here:
Why do model classes need to extend RealmObject?
We need to add Realm specific functionality to your model classes. It also allows us to use generics in our APIs, making it easier to read and use. If you don’t want to extend a base class you can instead implement the RealmModel interface.
and here:
An alternative to extending the RealmObject base class is implementing the RealmModel interface and adding the #RealmClass annotation.
It is a different means to achieve the same goal. The issue you experience is the same though. You cannot store plain objects in a realm. You must hook up your model class to Realm using one of two ways mentioned above.
Do note that if you use the 2nd approach, the usage is different:
// With RealmObject
myModel.isValid();
// With RealmModel
RealmObject.isValid(myModel);

ActiveAndroid ORM: extension model ierarchy

I want to use activeAndroid lib, but for now I faced with difficulties - I have BaseMessage class and plenty of sublasses, I want to pack them into one table, but it seems it's impossible.
Pseudocode:
#Table(name = "BaseMessage")
public class BaseMessage extends Model{
#Column(name = "messageContentType")
public int messageContentType;
...
public class MessagePhoto extends BaseMessage
I am using
BaseMessage.createMessage(...)
to create message of sertain type.
But when I add MessagePhoto type, it simply NOT put it into database.
Please show me the way to do it, or suggest any other ORM that can do such thing.

Extending an Android Parcelable class

I have a CustomAddress class that extends the android.location.Address class that implements Parcelable.
I am trying to make my CustomAddressimplement Parcelableto but am stuck when creating my class from a parcel. What I want to when creating CustomAddressfrom a parcel is first fill in all the fields from the super class Addressand then my own fields. So I have implemented the CREATORfield:
public static final Parcelable.Creator<CustomAddress> CREATOR
= new Parcelable.Creator<CustomAddress>() {
public CustomAddress createFromParcel(Parcel in) {
return new CustomAddress(in);
}
public CustomAddress[] newArray(int size) {
return new CustomAddress[size];
}
};
But in my CustomAddress(Parcel in)creator, I can't call super(in)because it doesn't exist in android.location.Address. I can only access android.location.Address.CREATOR. So how do I fill in my fields using CREATOR?
EDIT: link to the android Address class https://developer.android.com/reference/android/location/Address.html
Here is a similar question and Mark Murphy's excellent answer: https://stackoverflow.com/a/10841502/1140682
So, in your case, you would make CustomAddress extend Address (as you already do), call the super() method in the constructor and then read your own attributes from the passed Parcel. Same has to be done (in same order) in the writeToParcel() method, of course here adding your attributes to the parcel.

Android Parcelable and Serializable

So i know it is recommended to use Parcelable instead of Serializable in android, because it is faster.
My question is: is that impossible to avoid using Serializable right?
If I have a custom object i want to serialize, let's say I have the following class definition
public class Person {
String name;
int Age;
...
....
}
Making this parcelable is easy, because the Person class contains the types parcel.write*() supports, i.e. there is parcel.writeString and parcel.writeInt
Now, what if the Person class is the following:
public class PersonTwo {
MyCustomObj customObj;
String name;
int Age;
...
....
}
How am I suppose to parcel the MyCustomObj object??
It seems I need to use serializable again? but again, I thought it is SLOW to use serializable, and seems we have no choice but to use it in this case.
I don't understand
can someone tell me how I would parcel PersonTwo in this case?
The link given by Ajay is the exact what you are looking for, how you can do it.
Well, what you can do is implement Parcelable to your CustomObject1 and create a Parcelable class for it and then you can use that Parcelable class to Parcel it inside another Parcelable class that will Parcel both the CustomObjects.
public class CustomObject1 implements Parcelable {
// parcelable code CustomObject1
}
public class CustomObject2 implements Parcelable {
private CustomObject1 obj1;
// add CustomObject1 here with getter setter
// parcelable code for CustomObject2
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(obj1, flags);
}
private void readFromParcel(Parcel in) {
obj1 = in.readParcelable(CustomObject1.class.getClassLoader());
}
............
}
You need to make MyCustomObj parcelable.
All the composite objects should also be Parcelable. In case, you want to skip an object then don't use it writeToParcel method.
I came to point where Parcelable is an issue for me.
On Android 4.3, I am getting unmarhalling exception, when passing data between
Activities as Parcelable. It works OK on Android 4.0, 4.2 or 4.4.
It should work when changed to Serializable, even though, it is slower.

Categories

Resources