I have implemented a standard LRUCache in Android that stores Objects. Each key is a unique ObjectId associated with the Object stored. My problem is that the only way to retrieve an Object from cache is by the ObjectId (no iterator). What would be the best way to implement a getAll() method?
Another option would be to store all the ObjectIds in a list somewhere, so I can iterate over the lists and get all of the Objects - but what would be the best way of holding all of the ObjectIds?
Thanks!
If you're using (or extending) the LruCache that Android provides, it has a snapshot method that returns a map of keys (your ObjectIds) and values (your Objects). You can do something like this:
Map<ObjectIds, Object> snapshot = lruCache.snapshot();
for (ObjectIds id : snapshot.keySet()) {
Object myObject = lruCache.get(id);
}
If you're not using Android's LruCache, then I imagine it would depend on your implementation. (I'd also be curious what motivated you to implement your own instead of subclassing the provided one!)
Using snapshot to get current collection at the moment
lruCache.snapshot().values()
It does not make sense to iterate over the objects in a LRU cache. You can not know which object is still in the cache and which got evicted (you actually can, but that's another story). It sound like you'd probably better off with a different data structure like a Hashmap or so. Nothing will ever get evicted from there.
A common use-case is to have a List of all possible object keys in memory. If you need one, you check if it is in the cache. If not, receive it and add it to the cache.
Related
Suppose we have a list of complex objects (primitives and other objects inside) requested from a server to show them inside a RecycleView. In adapter we need only some data from each object, let's say 70%.
I get from server list with full data objects, and each object implements Parcelable so when I select a item I pass object via intent to MyDetailsActivity like so:
Intent intent = new Intent(context, MyDetailsActivity.class);
intent.putExtra("foo", myComplexObject);
startActivity(intent);
This is working as expected but on some low memory devices I get out of memory errors. So my question is how to achieve this type of data flow?
One possible solution is to implement get/set for MyObj in Applicattion class, and pass it like so but I'n not sure if it's stable.
And of course I can pass just an id from MyObject and do another request call inside DetailsActivity's onCreate(), but this requires user to wait some more seconds to load data.
Any advices or references are apreciated
As you have experienced, sending data through the bundle/intent extras has its memory limits.
Your options are to either keep those objects in memory and access them via some static/singleton instance or to do the data query from your server in the desired activity that will show them in your list.
Another viable options is to store the data in a database for ex and read it once its required but this ofcourse depends on your current architecture... you can checkout Realm, Room, GreenDao database options etc...
Second approach is more suitable for mobile applications since you only load data in list via API which is visible inside the recycler view, you can pass that data to activity and then in activity load the remaining data from another call for that specific item.
I'm assuming that each object of the data coming from the server is not of same size, leading to out of memory on some but not all the objects. So the better approach is to also modify server apt (if possible) to send only info which is required for the list in your call's response and have separate resource url to access full information for that object.
This may result in a minimal delay but it will not cause unexpected out of memory errors which is a big let down for the end user.
You can actually use Application class for this purpose, to make it even better
Set the data in Application class when you intend to pass
Retrieve the data at destination into Local variable from Application
After retrieving data into local variable, set object in Application to null
Using above approach will make sure your objects memory is released as soon you consumed it without holding it all the time throughout Application Lifecycle
I have a parseobject which consists of many objects, notably an array of consisting of ParseUser pointers.
When an individual clicks a button, the array should remove a certain User.
I don't get how to do this,
I have tried:
mRideEdit.removeAll("Participant", (Collection) childuser);
Where mRideEdit is my ParseClass, Participant is the array consisting of ParseUsers, and childuser is the user I want to remove
Please help,
I've recently faced the same problem.
It originates from how the ParseObjects (including ParseUser) are saved on the server.
If you look at the console, you'll see it is actually an array of strings created from the JSONObject toString method.
The simple answer is - You're using it wrong.
There is no sense in saving objects in such a way (though it's very intuitive).
As you probably noticed - you don't receive them as objects with the getJSONArray method either and have to get them from their objectIds.
The best way to do this is using relations.
If you're set on avoiding relations, what I'd suggest is saving them as strings from the get go (objectId). That way add, addUnique and removeAll will work just fine.
Hope this helps.
Just like it says on the tin. I have a decent sized object, consisting of about 20 variables, some of which are themselves android objects (Calendar, Uri). An arbitrary number of these objects are stored in a database.
I need to pass an individual object by intent to a broadcast receiver. When I create the intent I already have the entire object as a local variable and would not be querying the database. Is it more efficient to pass the entire object as a parcel, or to pass the database id and pull the object from the db in my onReceive method?
I suspect the former, but until yesterday I was doing the latter because I was too lazy to implement parcelable. I did, but now I'm second guessing myself.
P.S. I'm no CS major. In this case I define most efficient to mean least impact on user experience.
If the object in question is small (under 1MB), then going the Parcelable route should be more efficient. Basically, you avoid the disk I/O (and the accompanying complexity of trying to do that on a background thread when triggered by a broadcast).
I have a LongSparseArray variable, in which the objects stored implement the interface Comparable.
Is there a easy way to sort them, without do it "manually"?
I tried Collections.sort(myLongSparseArray), but it does not implements the List interface.
Another way could be convert it to a List, but still I have not found any method to do that.
SparseArray, or LongSparseArray, should be considered as an efficient hash table when the keys are integers or longs. As such, it is not the best class to use if ordering is important to you.
Usually, when using hash-table type data structures, then uniqueness of values & efficiency of get / set are important.
If this is the case, perhaps you should look into using LinkedHashSet? It provides a way of holding unique items (based on their hashCode & equals functions), but also preserves the order of items, and has high efficiency of get / set.
If sorting is important, then you could extract the value list from the LinkedHashSet, then place it in a List, and use Collections.Sort() on it.
I have an Android Class called Receipt, it's modeled off a typical Receipt you'd get in a retail environment and includes the following Class variables:
receipt_number
date_ordered
date_paid
item_quantity
item_type
item_sku
item_price
total_price
customer_id
customer_name
clerk_id
clerk_name
Whew... there's a lot. I'm just becoming accustom to OOP and while I love the idea of using a Receipt data Class to store the properties of a Receipt, I fear I am using an object just for the sake of using an object and not using data Classes appropriately.
Why? Well, I have another method in another Class which I feed my Receipt object to. Once fed to this other Class, the Receipt data is used to fill out a View which allows the user to edit said Receipt (data from the Receipt fills out EditText boxes which can be changed, then saved). The problem is that the code is getting ridiculous for updating a Receipt. I've got a helper method in Receipt for virtually every variable above (e.g. setClerkId(), setCustomerName(), setItemSku(), etc. etc.) and when I update a Receipt, I find myself calling all these methods and it's turning into a huge rats nest.
Surely I am missing the boat here, and probably by a long-shot. There must be a more sane way to feed in all the values of my new Receipt (it's really an update of the old object) without manually updating each variable using a helper method? I guess I'd be a little bit surprised (no, a lot surprised) if this is the correct way of doing this.
Any push in the right direction would be much appreciated!
Thanks!
You are doing it right I guess. I an object has a lot of named properties then you'll have to do a lot of get/set.
You can simplify that if you don't need to access each individually if you put them all into single (or several) ArrayList<String>/String[] or even other objects. Whatever you feel is an appropriate representation of your data.
Or you take a HashMap instead of your class and store them like so:
HashMap<String, String> hashmap = new HashMap<String, String>();
hashmap.put("receipt_number", value);
String value = hashmap.get("receipt_number");
That results in a more dynamic way to store values.