How to save Abstract object to Shared Preferences Android - android

I want to save abstract object to shared preferences.I get data with String from Shared preferences and when bind it to an Abstract class, I get some errors like that
"Caused by: java.lang.InstantiationException: Can't instantiate abstract class"
How to get abstract object from shared preferences?
Thanks

First of all, you cannot create an intance from an abstract class in java. You need to make something like this
public MyRealClass extends MyAbstractClass{
}
Your IDE should now tell you that you need to implement the needed methods from the abstract class.
You can now save the instance of MyRealClass to the SharedPreferences but only if you make it serializable or make the object to a JSON String. This can be done using libraries like GSON.
It is not possible to save an object to the SharedPrefs directly.
GSON will take your instance and transforms it into a string. This string can be saved and later if you need the object again you can give the string to GSON and it will transform it back into the object. The used representation is called JSON, which is a standard format (https://en.wikipedia.org/wiki/JSON)
To save
Gson gson = new Gson();
String json = gson.toJson(myRealClassInstance);
prefsEditor.putString("myobj", json);
prefsEditor.commit();
for later loading
Gson gson = new Gson();
String json = mPrefs.getString("myobj", "");
MyRealClass obj = gson.fromJson(json, MyRealClass.class);

For your Error: You can't create object of abstract class, you have to inherit abstract class to some class then only you can make an object to it.
Another one is, You can't store the object in shared preference. You can only store String, Integer, Boolean, Float, Long, and StringSet.
More info here.https://developer.android.com/reference/android/content/SharedPreferences.html

Related

GSON : Custom serialization for String

public class Data{
public String str; //String (that may contain line breaks) I need to serialize as it is.
}
Why I needed custom Serializer for string?
Without custom serializer it serializes this as object {"str":{"count": 292,"hashCode": 0} }
I need it to be {"str":"..............."}
How to do it with custom Serializer?
There are example of custom serializer for custom types, but could not find anything that helps to serialize String type.
Well, Gson supports strings out of box and you don't have to implement any string serializer and vice versa yourself. What I guess might happen to your case is merely importing a wrong string class, say import foo.bar.baz.String; or less obvious import foo.bar.baz.*, or you just have a String class implementation right in the package where your Data class is declared in. (This cannot explain what values were really assigned to str, though, -- it would never work in Java causing ClassCastException). A wrong class might be indicated with numeric count and hashCode without any char[]-declared fields, so I don't believe this is a java.lang.String in your case. Also, a more hypothetical thing here might be use of reflection that discarded the string type adapter out of your Gson instance, no matter how and how weird it sounds. In any case, you don't have to implement even a single line to serialize Java strings with Gson.
Regarding the accepted answer: it is suboptimal. If, for whatever reason, there is nothing wrong with your imports, your package does not declare a custom String class, and your Gson instances do not suffer from reflection surgery, but Gson still serializes such strings as nested objects (have no ideas why then), you'd only need a single special String type adapter without any need of creating type adapters for any class that uses that weird String as a field:
final Gson gson = new GsonBuilder()
.registerTypeAdapter(/*real.package.here.*/String.class, (JsonSerializer</*real.package.here.*/String>) (s, type, context) -> new JsonPrimitive(s.toString())) // whatever the real Java string is obtained
.create();
Try this
public class DataSerializer implements JsonSerializer<Data> {
#Override
public JsonElement serialize(Data data, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject();
object.addProperty("src", data.src);
return object;
}
}
Add this to Gson Like this
Gson gson = new GsonBuilder()
.registerTypeAdapter(Data.class, new DataSerializer())
.create();

Android Parcelable with JsonObject

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

How do I set the intent extra dynamically based on the type of variable received in the Json?

I have a Json in a server response which has the entire intent data. I also get extras to be added to the intent.
Now, the extras can vary in data type. int, long, boolean etc.
How do I pass these extra values to the intent which I create in the necessary type?
The putExtra method has string as a key and a few overloads based upon the type of value.
How do I decide which one to use?
Parse the json using gson library http://www.java2s.com/Code/Jar/g/Downloadgson222jar.htm
create the model class and implements serializable.
Example:-
public class TemplateCommonMetaData implements Serializable {
#SerializedName("code")
public boolean sCode;
#SerializedName("message")
public String message; }
and set serializable objet in intent
in.putExtra("key", serializableobject);
It depends on contracts of json parser, Intent receiver.
If protocol is undefined - heuristically (switch, if/else).
Also you can try gson, it doesn't solve problem with types, but transit can be easier.

how to pass the ArrayList<data class> from one activity to another activity android

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");

JSONObject as class attribute storage/retrieval

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.

Categories

Resources