Android save array of custom objects - android

I have a question about saving an arraylist of custom objects. I have a class called notitie:
public class Notitie implements Serializable{
private String titel = "";
private String type = "";
private String datum = "";
public void setTitel (String titel){
this.titel = titel;
}
public String getTitel(){
return titel;
}
public void setType (String type){
this.type = type;
}
public String getType(){
return type;
}
public void setDatum (String datum){
this.datum = datum;
}
public String getDatum(){
return datum;
}
}
I create some objects of Notitie and add them to my arraylist called notities
ArrayList<Notitie> notities = new ArrayList<Notitie>();
Notitie notitie1 = new Notitie();
notitie1.setTitel("Meting");
notitie1.setType("Watermeting");
notitie1.setDatum("22-09-12");
notities.add(notitie1);
Notitie notitie2 = new Notitie();
notitie1.setTitel("Meting2");
notitie1.setType("Watermeting2");
notitie1.setDatum("23-09-12");
notities.add(notitie2);
Notitie notitie3 = new Notitie();
notitie1.setTitel("Meting3");
notitie1.setType("Watermeting3");
notitie1.setDatum("24-09-12");
notities.add(notitie3);
Now I want to save the filled Arraylist on the device's storage so it can be accessed anytime. I used to save data as a String or some Integers with sharedpreferences but I can't save this Arraylist with that.
Does anybody have a solution?
Thanks in advance!

You do have a few options:
Use serialization, XML or JSON, and store your data in a File. Refer to this solution if you wanna implement serialization.
Store you data using SQLite. Have a look at this tutorial to get started.
EDIT : You might want to read this as well!

Related

Cannot read List with Gson afer writing

I want to save and read List<MyObj> to sharedPreferences using Gson.
This is my write method:
private static final String GAS_STATIONS_LIST_KEY = "gasStationsListKey";
#Override
public void save(#NonNull List<MyObj> gasStations) {
saveStr(GAS_STATIONS_LIST_KEY, gson.toJson(gasStations));
}
private void saveStr(#NonNull String key, #Nullable String value) {
sharedPreferences
.edit()
.putString(key, value)
.apply();
}
And this is my read method:
#Override
public List<MyObj> getGasStationList() {
final Type type = new TypeToken<List<MyObj>>() {
}.getClass();
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type); // here null
if (gasStations != null && !gasStations.isEmpty()) {
return gasStations;
} else {
return new ArrayList<>();
}
}
But when I try read data I get null (comment in last code part).
How to fix it?
You are not getting the saved json content from shared prefences. You are trying to deserialize the key to a list, not the json content which is saved with that key.
Change this:
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type);
To this:
String savedJsonContent = sharedPreferences.getString(GAS_STATIONS_LIST_KEY, null);
final List<MyObj> gasStations = gson.fromJson(savedJsonContent , type);
SharedPreferences only store primitive data Types.

Performance comparison custom class versus arrays

Is it more performant to create a class
public class test {
private Circle c;
private String mac;
private Short abstand;
private Location ort;
public test (String mac, Circle c, Short abstand, Location ort){
this.c = c;
this.mac = mac;
this.abstand = abstand;
this.ort = ort;
}
public String erhalteMac()
{
return mac;
}
//etc.
}
Create an array list by using
ArrayList<test> karte = new ArrayList<test>();
and adding
test t = new test();
t.mac = "...";
karte.add(t);
etc.
to then see if there is an object that has a certain property
public static boolean hM(ArrayList<object> list, String mac) {
for (object object2 : list) {
if (object2.erhalteMac().equals(mac))
{
//work with object2 here.
return true;
}
}
return false;
}
versus simply creating four arrays for each type and iterating through only the mac array in my case and use the index of the matching mac string in each other array to make changes?
The Array method would be a tiny bit faster than the simple List, but
a HashMap would be a lot faster when there are more than a few object instances.

How to save Object (includes Array) in Preferences?

How to save Object in Preferences which looks like this:
public class ToDoList {
public String name;
public String date;
public ArrayList<Product> products = new ArrayList<Product>();
public boolean isChecked;
}
and then loads its values?
You could do it with serialization. Serialization of an object is a short unique String format of an object that can be serialized. Particularly almost every object can be serialized in java except from the View object. You won't have any problem in your case.
How to do it:
You should make class ToDoList implement Serializable and all classes that are used inside your object, ex Product. String, boolean ArrayList are serializable so you don't have to do anything.
When implementing serialization in an object you have to supply a serial version UID which would be then used to serialize.
So ToDoList would be something like:
public class ToDoList implelements Serializable {
private static final long serialVersionUID = //generate random by eclipse
.....
public ArrayList<Product> products = new ArrayList<Product>();
}
and Product:
public class Product implelements Serializable {
private static final long serialVersionUID = //generate random by eclipse
.....
}
then include this static helper class:
public class ObjectSerializeDeserialize {
public static String ObjectSerialization(Object obj)
{
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
try
{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArray);
objectOutputStream.writeObject(obj);
objectOutputStream.close();
}
catch (Exception e) {
e.printStackTrace();
return "";
}
return new String(Base64.encode(byteArray.toByteArray(), 0));
}
public static Object ObjectDeserialization(String str)
{
byte[] byteArray = Base64.decode(str,0);
Object o;
try
{
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArray));
o = ois.readObject();
ois.close();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
return o;
}
}
and simply use the following code:
String todolistSer = ObjectSerializeDeserialize.ObjectSerialization(todolistObj);
the above line of code will return an empty String if something goes wrong and will print the detailed message in the log cat.
Then simply save the todolistSer as a String in preferences and reclaim your object like this:
ToDoList todolistObj = (ToDoList) ObjectSerializeDeserialize.ObjectDeserialization(todolistString);
suppress any warnings that are issued by the above method and you are done!
P.S. you can use the above solution whenever you have complicated structures that can not be saved as raw variables and you still don't want to use a database
Preferences are simple key ,value pairs. In your case better use SQLite.

Android Bundle corrupted when passing between activities?

I'm trying to pass an ArrayList of Parcelable objects plus a string value between two activities. This is the code to add the data to the intent and pass it through:
Intent intent = new Intent(this, DisplayLotListActivity.class);
Bundle dataBundle = new Bundle();
dataBundle.putParcelableArrayList(DisplayLotListActivity.EXTRA_LOT_ARRAY, lotList);
dataBundle.putString(EXTRA_LOT_NUMBER, lotNumber);
intent.putExtra(DisplayLotListActivity.EXTRA_DATA, dataBundle);
startActivity(intent);
This is the code that I'm using to get the data out of the intent on the target activity:
Intent intent = getIntent();
Bundle dataBundle = intent.getBundleExtra(EXTRA_DATA);
lotList = dataBundle.getParcelableArrayList(EXTRA_LOT_ARRAY);
lotNumber = dataBundle.getString(LotInquiryActivity.EXTRA_LOT_NUMBER);
When I check the debugger the data structures look correct before the activity is called but when I get into the target activity the data structure has been corrupted. Specifically the ArrayList as 3 elements and it is still 3 elements in size but the second element is null. There is then an additional extra in the bundle which contains the missing element object with a null key. I have images of the debugger before and after but can't put them in the post because of anti-spam rules.
Before: http://i.stack.imgur.com/vDipq.png
After: http://i.stack.imgur.com/JqbF7.png
Is there something I'm missing? This issue occurs whether I use a Bundle or add the ArrayList directly to the intent. This is being run on a Samsung Tab 2 running 4.0.3. This also occurs with a 4.0 emulator.
[Edit]
This is the Parcelable object being used (I've just left the getter and setter methods off the bottom)
public class Lot implements Parcelable{
private String lotn;
private String dsc1;
private String dsc2;
private String litm;
private long itm;
private String locn;
private String mcu;
private String uom1;
private String uom2;
private BigDecimal pqav;
private BigDecimal pqoh;
private BigDecimal sqoh;
private long vend;
private String rlot;
private String ldsc;
private String lots;
private String lot1;
private String lot2;
private String lot3;
private String lotsdsc;
private XMLGregorianCalendar mmej;
private XMLGregorianCalendar ohdj;
public Lot(){
}
public Lot(Parcel source){
lotn = source.readString();
dsc1 = source.readString();
dsc2 = source.readString();
litm = source.readString();
locn = source.readString();
mcu = source.readString();
uom1 = source.readString();
uom2 = source.readString();
itm = source.readLong();
pqav = new BigDecimal(source.readString());
pqoh = new BigDecimal(source.readString());
sqoh = new BigDecimal(source.readString());
vend = source.readLong();
rlot = source.readString();
ldsc = source.readString();
lots = source.readString();
lot1 = source.readString();
lot2 = source.readString();
lot3 = source.readString();
lotsdsc = source.readString();
try{
mmej = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
}catch (Exception exc){
mmej = null;
}
try{
ohdj = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
}catch (Exception exc){
ohdj = null;
}
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(lotn);
dest.writeString(dsc1);
dest.writeString(dsc2);
dest.writeString(litm);
dest.writeString(locn);
dest.writeString(mcu);
dest.writeString(uom1);
dest.writeString(uom2);
dest.writeLong(itm);
if(pqav != null){
dest.writeString(pqav.toPlainString());
} else {
dest.writeString("0");
}
if(pqoh != null){
dest.writeString(pqoh.toPlainString());
} else {
dest.writeString("0");
}
if(sqoh != null){
dest.writeString(sqoh.toPlainString());
} else {
dest.writeString("0");
}
dest.writeLong(vend);
dest.writeString(rlot);
dest.writeString(ldsc);
dest.writeString(lots);
dest.writeString(lot1);
dest.writeString(lot2);
dest.writeString(lot3);
dest.writeString(lotsdsc);
if(mmej != null){
dest.writeString(mmej.toXMLFormat());
} else {
dest.writeString("");
}
if(ohdj != null){
dest.writeString(ohdj.toXMLFormat());
} else {
dest.writeString("");
}
}
/**
*
*/
public static final Parcelable.Creator<Lot> CREATOR
= new Parcelable.Creator<Lot>() {
public Lot createFromParcel(Parcel in) {
return new Lot(in);
}
public Lot[] newArray(int size) {
return new Lot[size];
}
};
OK, for anyone that comes back to this question there's two problems that I found which I assume combined to cause this behavior. The issues all related to the Parcelable object I was using so thanks to Todd for at least pointing me in this direction.
Firstly, I had a simple error where I had missed a readString() in my constructor of the Parcelable object. So basically I was writing out n elements and reading in n - 1 elements. The second issue is that Android does not implement the javax.xml.datatype library which means that XMLGregorianCalendar is not available. As I didn't need the features of this class on the client side (there's a Java Web Application that it talks to which does use it) I just converted over to a simple java.util.Date object instead.

How to store a value in HashMap (Android)?

im worked in soap message, using SAXparser to retrieve the value(from Webservice) stored in ArrayList and the ArrayList working fine, but i want to store in HashMap, because Using key to identify a each name has certain SystemId, Please any one help me
Thanks
I tried the code:
public class SitesList
{
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> systemid = new ArrayList<String>();
//Map <String,String> map = new HashMap<String,String>();
public ArrayList<String> getName()
{
return name;
}
public void setName(String nameString)
{
this.name.add(nameString);
System.out.println("name "+ name);
}
public ArrayList<String> getSystemId()
{
return systemid;
}
public void setSystemId(String systemidString)
{
this.systemid.add(systemidString);
System.out.println("systemid "+systemid);
}
you can store like this way
you arraylist for name
private ArrayList<String> name = new ArrayList<String>();
and HashMap like this way
HashMap<String, ArrayList<String>>h = new HashMap<String, ArrayList<String>>();
and you can store your arraylist like this way
h.put("name", name);
If you don't need to preserve the order of entries, you can do something like this:
public class SitesList {
private final Map <String,String> map = new HashMap<String,String>();
public Set<String> getNames() {
return map.keySet();
}
public void add(String nameString, String systemidString) {
map.put(nameString, systemidString);
}
public Collection<String> getSystemIds() {
return map.values(); // may contain duplicates
}
}

Categories

Resources