How can I put an array of arrayList into a Bundle?
ArrayList < myObjects >[] mElements;
Make YourObject implement the Parcelable interface, then use bundle.putParcelableArraylist(theParcelableArraylist).
Edit: whoops misread the question. Why do you want to save an array of arraylist? If its for persisting in an orientation change, maybe you want to use onRetainNonConfigurationInstance instead?
Edit 2: Ok, here goes. Create a new Wrapper class that implements Parcelable (note that myObjects also have to be parcelable). The writeToParcel method will look something like this:
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mElements.length);
for(ArrayList<MyObject> element : mElements) {
dest.writeParcelableArray(element.toArray(new MyObject[0]), flags);
}
}
And the constructor:
private Wrapper(Parcel in) {
int length = in.readInt();
//Declare list
for (int i = 0; i < length; i++) {
MyObject[] read = in.readParcelableArray(Wrapper.class.getClassLoader());
//add to list
}
}
Not possible using bundle, as bundle allows arraylist of primitives only...
Try to use parcleable or application level data or static variable (bad practice).
If your objects support serialization, marked with the Serializable interface, then you should be able to use bundle.putSerializable.
ArrayList supports Serializable , but I'm not sure about a plain array.
I just use putSerializable(myarraylistofstuff) and then I get back with a cast using get(), you just need to silence the unchecked warning. I suspect (correct me if wrong) you can pass any object faking it as Serializable, as long you stay in the same process it will pass the object reference. This approach obviously does not work when passing data to another application.
EDIT: Currently android passes the reference only between fragment, I've tried to pass an arbitrary object to an Activity, it worked but the object was different, same test using arguments of Fragment showed same Object instead.
Anyway it deserializes and serializes fine my Object, if you have a lot of objects it's better to use Parcel instead
Related
i have a POJO object defined like this:
public class MYPOJO implements Serializable {
int myint;
String mystring;
}
then when im passing the info to an activity i do this:
Intent i = new Intent(this, WearActivity.class);
Bundle b = new Bundle();
MYPojo pojo = new MYPojo();
pojo.mystring="cool";
b.putSerializable("someString", pojo.mystring);//this line is my issue
i.putExtra("coolBundle",b);
startActivityForResult(i, 0);
and to read the 'someString' extra i do:
Bundle b2 = getIntent().getBundleExtra("coolBundle");
b2.getString("someString");
So now onto my question: is there really any difference if i do the following if if at the end im still calling for retrieval b2.getString("someString") :
b.putString("someString",pojo.mystring)
vs
b.putSerializable("someString",pojo.mystring) ?
In practice, there isn't a difference you'll see between passing a string, or passing a serializable string between activities, besides "efficiency" or possible usage of reflection/security. It might be more of a design and principle issue I have with passing a String in as "serializable". Essentially by passing in a String as Serializable, Android/Java will utilize the wrapper of String, which contains a data structure of char[] behind the scenes.
TLDR; If your POJO contained more data, I would highly recommend implementing Parcelable. More information can be found in this SO answer here. But if you are going to be passing just a String, I would use the putString/getString methods that Android provides for us.
I use eclipse android
I need to index or object find in ArrayList
public class myclass
{
int id;
int count;
String value;
}
mainactivity
{
ArrayList<myclass> list = new ArrayList<myclass>();
myclass mc = new myclass();
mc.id=1;
mc.count=20;
mc.value="my value 1"
list.add(mc);
//add 100 record in list
//how can i this
int index = list.find(value="search value");
//or this
myclass founded = list.find(value="search value");
//or this
myclass founded2 = list.where(a => a.value="search value").first; //yes this is linq and lambda, but i cant linq in android
}
if I use for loop, I can find index but maybe arraylist has 1billion over record and I search 1000 values in arraylist
I dont want to use 1000 times for-loop in arraylist.
how can I this basicly
You can use indexOf()
int index = list.indexOf(object)
So if you want to find 1000 values inside your 1billion ArrayList record it is better not to use ArrayList here.
More preferable way for doing that is using HashMap<String, YourClass>.
Where first parameter is your id and second is element of your class.
You can easily found then element of your class by id. Approximately O(1).
If it is no matter how your values will be stored in ArrayList you can implements comparable interface in your class and support your collection in sorted way. So if your collection is sorted you can find your element with binary search.
You should use this version of binary search
Collections.binarySearch(List<? extends T> list, T object, Comparator<? super T> comparator)
So you can implement you custom compator to check if your object is equal to something that you are finding.
I'd like to pass a custom Object from one activity to another, the Object consists of a String and a List of another custom Object which consists of an array of strings and an array of ints. I've read https://stackoverflow.com/a/2141166/830104, but then I've found this answer https://stackoverflow.com/a/7842273/830104. Which is better to use Bundle or Parcelable? What is the difference? When should I use this each? Thanks for your replies, Dan
Parcelable and Bundle are not exclusive concepts; you can even deploy both on your app at a time.
[1] Term Parcelable comes with Serialization concept in Java (and other high-level language such as C#, Python,...). It ensures that an object - which remains in RAM store - of such Parcelable class can be saved in file stream such as text or memory (offline status) then can be reconstructed to be used in program at runtime (online status).
In an Android application, within 2 independent activities (exclusively running - one starts then other will have to stop):
There will be NO pointer from current activity to refer to previous one and its members - because previous activity is stopped and cleared out form memory; so that to maintain object's value passed to next activity (called from Intent) the object need to be parcelable (serializable).
[2] While Bundle is normally the Android concept, denotes that a variable or group of variables. If look into lower level, it can be considered as HashMap with key-value pairs.
Conclusion:
Bundle is to store many objects with related keys, it can save any object in native types, but it doesn't know how to save a complex object (which contains an ArrayList for example)
Parcelable class is to ensure a complex instance of it can be serialized and de-serialized during runtime. This object can contains complex types such as ArrayList, HashMap, array, or struct,...
[UPDATED] - Example:
//Class without implementing Parcelable will cause error
//if passing though activities via Intent
public class NoneParcelable
{
private ArrayList<String> nameList = new ArrayList<String>();
public NoneParcelable()
{
nameList.add("abc");
nameList.add("xyz");
}
}
//Parcelable Class's objects can be exchanged
public class GoodParcelable implements Parcelable
{
private ArrayList<String> nameList = new ArrayList<String>();
public GoodParcelable()
{
nameList.add("Can");
nameList.add("be parsed");
}
#Override
public int describeContents()
{
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags)
{
// Serialize ArrayList name here
}
}
In source activity:
NoneParcelable nonePcl = new NoneParcelable();
GoodParcelable goodPcl = new GoodParcelable();
int count = 100;
Intent i = new Intent(...);
i.putExtra("NONE_P",nonePcl);
i.putExtra("GOOD_P",goodPcl);
i.putExtra("COUNT", count);
In destination activity:
Intent i = getIntent();
//this is BAD:
NoneParcelable nP = (NoneParcelable)i.getExtra("NONE_P"); //BAD code
//these are OK:
int count = (int)i.getExtra("COUNT");//OK
GoodParcelable myParcelableObject=(GoodParcelable)i.getParcelableExtra("GOOD_P");// OK
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.
I want to persist an object with two foreignCollections.
But when I try to query the object, my foreignId is always null.
I already read this answers but it doesn't really help me: Collections in ORMLite
VOPerception perception = new VOPerception();
perception.setOrientation(daoOrientation.createIfNotExists(
orientationLocalizer.getCurrentOrientation()));
ForeignCollection<VOAccessPoint> fAp =
daoPerception.getEmptyForeignCollection("accessPoints");
fAp.addAll(wifiLocalizer.getCurrentScanResultMap());
perception.setAccessPoints(fAp);
daoPerception.create(perception);
List<VOPerception> list = daoPerception.queryForAll();
here data are correctly stored but VOAccessPoint objects have no link with the parent VOPerception object.
Here are my two classes:
public class VOPerception {
#DatabaseField(generatedId=true)
private int per_id;
#ForeignCollectionField(eager=true)
ForeignCollection<VOAccessPoint> accessPoints;
...
}
public class VOAccessPoint{
#DatabaseField(generatedId=true)
private int ap_id;
#DatabaseField(foreign=true,columnName="apForeignPerception_id")
private VOPerception apForeignPerception;
...
}
Your queryForAll() is returning no objects because none of your VOAccessPoint instances ever set their apForeignPerception field to be perception. Adding the VOAccessPoint objects using the ForeignCollection added them to the DAO but did not automagically assign their apForeignPerception field.
You should do something like:
...
Collection<VOAccessPoint> points = wifiLocalizer.getCurrentScanResultMap();
for (VOAccessPoint point : points) {
point.setApForeignPerception(perception);
}
fAp.addAll(points);
...
I can see how you might think that this would be handled automagically but at the time they are added to the ForeignCollection, the perception is not even assigned. I suspect that there is a missing feature for ORMLite here or at least a better exception.
I would recommend to use assignEmptyForeignCollection(Obj parent, fieldName). This will create a new foreign collection and all objects you will add via add(Obj element) will have the parent value set automatically.