In order to initialize my new Fragment, I need to send an object as parcelable one.
These are the fields it contains:
private String sessionId;
private String status;
private JSONObject typeAttributes;
private JSONObject kindAttributes;
The problem is that JSONObject is not parcelable. If I just use writeValue method in writeToParcel method, I get unacceptable class error.
Moreover, JSONObject is not even Serializable.
Also, typeAttributes and kindAttributes are dynamic, so each time my app starts they have different fields with different values.
If anyone knows how to solve it, please help.
I would use JSONObject's toString() method to return a String which you can easily save to a parcel.
Then to create the object from the parceled String, just use the JSONObject constructor that takes a String and it'll auto-populate those object's fields for you.
I would go with this approach.
1- Create a Pojo class which implements serializable
2- Build the object of that class
3- Send the Object as serialazable one
public class POJO implements Serializable{
private String sessionId;
private String status;
// private JSONObject typeAttributes;
// SUPPOSE THIS JSONObject CONTAINS TWO FIELDS AS NAME AND AGE SO I USE TWO MORE FILDS
String name;
String age;
//....... WRITE GETTERS AND SETTERS
}
Let me know if you need further explanation for building this POJO object Inside activity and then send it to as a serializable
Related
I decided to use Room for caching data and now because of the situation of the library that I developed, I need to hide some fields of my model and then give them to the client that use my library.
The model below had orderId and I added this because I need that but when I don't want to give this filled model with orderId. i know how to ignore fields in JSON. But how can i hide this one from my model and then give it to the client.
Do I make a mistake in using Room in the first place?
public class Participant {
#PrimaryKey
private long id;
#ColumnInfo(name = "order_id")
private long orderId;
private long threadId;
private String name;
private String firstName;
private String lastName;
For example :
i have a listener that is like the below
listener.add(participant);
i want to hide orderId first and then pass it to the listener.
Then in another class override this:
#Override
public void onAdd(Paticipant participant) {
super.onAdd(participant);
//here
}
One way to hide orderId from classes which use Participant, is to provide a getter for this variable and return null:
public Long getOrderId() {
return null;
}
We must change orderId to a Long in order for it to be set as null.
Additionally, you can override the toString() method to ignore orderId in any string representations of the class.
Use GSON library and create a new class for JSON model, without orderId:
class ParticipantJson {
final long id;
final long threadId;
final String name;
final String firstName;
final String lastName;
// Constructor
}
Then you can create JSON representation with:
ParticipantJson participant = new ParticipantJson(/* fields from Room model */);
Gson gson = new Gson();
String json = gson.toJson(participant);
USE A DIFFERENT MODEL FOR PRESENTATION!
Sorry for the caps but I cannot emphasize how important it is to use a different model for presentation.
Although you can hide fields from libraries like GSON or ROOM using keywords like transient or annotation like ignore you cannot hide a model attribute from class itself. Also remember that you cannot enforce a rule on a model that is not designed for the purpose.
TLDR; Create a new model and using a mapper map the Room model to this new presentation model.
I've been trying to add Realm in my Android app. Their docs are pretty well explained & easy to follow. But it fails to explain this one particular area. I'm unable to figure out the practical use for the #Ignore annotation. I know that fields under this annotation are not persisted.
Can someone please share a few use cases. Also I wanted to know the scope of such fields. I mean, if I set an #Ignore field to some value, would that value be available to the other classes in my app for that particular launch session. If yes, then how do we access it? If no (which I guess is the case), then why do we need such a field anyway?
I've searched here and on web but couldn't find the relevant information. If out of my ignorance, I've missed upon some resource, please guide me to it.
Thanks.
Accordingly to the official documentation (see https://realm.io/docs/java/latest/) #Ignore is useful in two cases:
When you use GSON integration and your JSON contains more data than you want to store, but you still would like to parse it, and use right after.
You can't create custom getters and setter in classes extending RealmObject, since they are going to be overridden. But in case you want to have some custom logic anyway, ignored fields can be used as a hack to do that, because Realm doesn't override their getter & setters. Example:
package io.realm.entities;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
public class StringOnly extends RealmObject {
private String name;
#Ignore
private String kingName;
// custom setter
public void setKingName(String kingName) { setName("King " + kingName); }
// custom getter
public String getKingName() { return getName(); }
// setter and getter for 'name'
}
Ignored fields are accessible only from the object they were set in (same as with regular objects in Java).
UPDATE: As the #The-null-Pointer- pointed out in the comments the second point is out of date. Realm now allows having custom getters and setters in Realm models.
Here's a couple of real-world use cases:
1 - Get user's fullname:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private String fullName;
public String getFullName() {
return getFirst() + " " + getLast();
}
Get JSON representation of object:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private JSONObject Json;
public JSONObject getJson() {
try {
JSONObject dict = new JSONObject();
dict.put("first", getFirst());
dict.put("last", getLast());
return dict;
} catch (JSONException e) {
// log the exception
}
return null;
}
I've found it useful to define field names for when I am querying. For example
User.java
public class User extends RealmObject {
#Index
public String name;
#Ignore
public static final String NAME = "name";
}
And then later on I can do something like:
realm.where(User.class).equalTo(User.NAME, "John").findFirst();
This way if the schema changes from say name to id I don't have to hunt down every occurrence of "name".
Please see the the official documentation about #Ignore annotation:
The annotation #Ignore implies that a field should not be persisted to disk. Ignored fields are useful if your input contains more fields than your model, and you don’t wish to have many special cases for handling these unused data fields.
i want to Pass Hash_set object when click on button,object pass from one fragment to another fragment. in Hash_set object I Put multiple Parse Object in Hash_set object .How to do it ? i tried with Intent and Bundle but not get successful to pass object.
please provide me any best idea. thanks `
You can Also use Application.
step1:Use this class
public class JsonApplication extends Application {
public JSONObject jsonObject;
public JSONObject getJsonObject() {
return jsonObject;
}
public void setJsonObject(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}}
step2: set data and get data as your desire
Simply, create an static object of your hashset in the activity like this,
public static Set<YourObject> mObject = new HashSet<YourObject>();
and from your BaseAdapter-button-onClick call it in this way,
ActivityName.mObject = mYourHashSet;
A public static field/method
An alternate way to make data accessible across Activities/Services is
to use public static fields and/or methods. You can access these
static fields from any other class in your application. To share an
object, the activity which creates your object sets a static field to
point to this object and any other activity that wants to use this
object just accesses this static field.
Other way todo this,
In you baseAdapter-onClick, convert it to JSONObject like that,
JSONObject multiple = new JSONObject();
multiple.put("hash_set_object", mHashSetObject);
Intent ii = new Intent(mActivity, ActivityName.class);
ii.putExtra("hash_set_json", multiple.toString());
startActivity(ii);
In Activity's onCreate call it in this way,
String HashString = getIntent().getExtras().getString("hash_set_json");
JSONArray array = new JSONArray(new JsonObject(HashString).getString("hash_set_object"));
//Now make for-loop to re-populate hashSet from JSONArray
In my application whenever we click the "SEARCH" button it makes Http call and get the json as response. I parsed the json and save the data in arraylist bdata.
ArrayList bdata = new ArrayList();
BusData contain getters and setters . I also used one adapter class for custom listview.
now i want to set the adapter to listview but the listview is in another class (not in the class where search button is locate) so how to send my arraylist from one activity to another activity with the help of intents for set the adapter to listview.
Thank you.
A way to do this is by serializing your arraylist to a JSON.
Use GSON library
compile 'com.google.code.gson:gson:2.3.1'
Add the above line in your build.gradle file.
Make a class to help you serializing your objects
public class SerializationHelper {
private static Gson gson = new Gson();
public static String serialize(Object object) {
return gson.toJson(object);
}
public static Object deserialize(String json, Class classType) {
return gson.fromJson(json, classType);
}
}
Now when you want to start the new activity add the serialized string.
String json=SerializationHelper.serialize(myArrayList);
intent.putExtra("data",json);
And in your new activity on create get it and create your object again.
String json=intent.getStringExtra("data");
Object deserializedObject=SerializationHelper.deserialize(json,ArrayList.class);
Now cast your object!
ArrayList<MyClass> myCoolArray=(ArrayList<MyClass>)deserializedObject.
Other simpler way is to make your arraylist static and public, and store it in an other class.
public class GlobalStuff{
public static ArrayList<MyClass> myAwesomeList;
}
Now acces your list by GlobalStuff.myAwesomeList.
You need to create custom class (ArrayList<data class>) to Parcelable and then you can pass it to other activity.
http://androidideasblog.blogspot.in/2010/02/passing-list-of-objects-between.html
When passing data through activities you should use Parcelable, the are many examples in stackoverflow, this one is good:
https://stackoverflow.com/a/22446641/2091315
Next, you need to configure the intent, on the "sender" Activity:
Intent intent = new Intent(getApplicationContext(),
ReceiverActivity.class);
intent.putExtra("arrayListIdentifier",parcelableArrayClass);
startActivity(intent);
On the "receiver" Activity:
parcelableArrayClass myParcelableObject = (parcelableArrayClass) getIntent().getParcelableExtra("arrayListIdentifier");
In android, I'm using model classes with methods to handle the data manipulation. My data is brought in from webservices as json. I'm contemplating the possibility of using JSONObjects to store the values of class level attributes. But, I don't know of a way to use the JSONObj as the "holder" variable and create access methods. I don't want to predetermine these methods, as jsonRepository should hold the values, not always known at design time
For example, I'd like to have:
public class User {
private JSONObject jsonAttributes;
public User(String json) {
this.jsonAttributes= new JSONObject(json);
}
[IMPLICIT attribute access methods]
public string Prop1() returns jsonAttributes.getString("prop1");
public string Prop1(String newProp1) returns jsonAttributes.putString("prop1",newProp1);
public string Prop2() returns jsonRepository.getString("id");
public string Prop2(String newProp2) returns jsonAttributes.putString("prop2",newProp2);
....
from outside this class then, I would access the attributes simply...
User myUser = new User(someValidJson);
String myString = myUser.Prop1
Misguided? If not, how does one manage implicit property setting/getting?
As was mentioned in the comment above, why not create your user class, with all of the relevant memeber variables, and simply parse your JSON data in order to populate the ionformation in your user class.
There are a lot of ways you can do this, but I would consider using the builder pattern, as it is flexible, which could be useful if your JSON data changes in the future.