Storing complex object graphs in Parcelable? - android

Existing Parcelable examples are rather trivial. If you have a complex object graph the following questions arise quickly questioning the feasibility:
Is there any way to prevent an object being written multiple time into a parcel?
Are there any best practices to limit the depth of the object graph while writing?
To give an example for the first question, object A references B, which in turn references A. This cycle leads to writes A, B, A, B, A, ... until we get an StackOverflowError because there does not seem to be a way to just reference an object that was previously written.
For the second question let's we have a long graph A->B->C->D->E, and we want to serialize A with an additional depth of 2, which would be just A->B->C. We did this by writing a custom writeToParcelDeep method, which is of course not as convenient as the standard writeToParcel.

Java serialization will preserve reference and write a object just once. Also current devices are much more powerful than the ones from the past and I'm not so sure that performance gain is justifying writing Parcelable biolerplate code especially complicated one as in your example.
I'll keep using serializable and you can read more about my findings on this topic here.

Related

Is setting fields line after line from a Firestore document read an anti-pattern?

I have a document on Firestore, from which I read its fields in a fragment. Since it has many fields, I set variables in the Activity that hosts this fragment so that I can pass the data between other fragments. In order to achieve that, I realize that I have to write similar lines of codes over and over again, which got me to thinking if there is a better way.
Two possible solutions that come to my mind:
Structure all these fields in JSON format -> something that wouldn't be suitable in Firestore's document system imo
Put all these fields into a serializable data class which I keep in the activity then pass it around the bundles of fragments -> Seemed to complicated and I would still have to write it.get(foo) as bar for each of the field's of this class' constructor.
Given all these, what is the best approach? Thanks in advance.
You have a several options on how to approach this. There is none that's necessarily better than another. Ultimately, you will pick the one that best suits your needs and preferences.
You can do what you're doing now.
You can go a step further an actually check the types of the values instead of just blindly casting them (which would cause a crash at runtime if they didn't match).
You can provide a Class object to get(String, Class<T>) that can automatically map the fields to properties in a new object of type T, as long as the types also match.
You can call a variety of type-specific versions of get, such as getString()
Ultimately you will have to decide if you are going to trust what you get in the snapshot and allow errors to happen, or trust nothing and check everything. It's up to you.

Android: OpenGL ES: associating information with drawn objects

I have a fairly basic question that I cannot for the life of me find the answer to online (most definitely due to not really knowing what I am looking for).
Suppose I have multiple (for the most part static) objects that are stored inside one VBO and drawn to the screen. Each object will have images and text/external data associated with it. I need to be able to navigate this "map" of objects and on-tap, access the corresponding information.
My question is, what is the best practice when it comes to storing this corresponding data and linking it to its respective drawing? I figured you create a "parallel" array of custom objects that each references its drawing and holds all the data... Although it seems quite elementary and thought there might be a better way. Considering also that there will potentially be thousands of these objects on the "map".
You can Use model class and put all common data intro one entity than use extends. You can use yours custom object who will consider whole VBO or opengles program data. About identity make ID for each elementary object or "draws".
-I understand your problematic. In opengl/es procedural programming is actually on scene.
Remember you are still in android envelopment you can use any java/android methodology.
-When you say "tap" did you mean click? If you so than see "Raycast" thema.
-This is interest file . It is JS not android but you can use same logic methods to make your object based app.
https://github.com/zlatnaspirala/visualjs/blob/master/project/project_instance_webgl2/lib/matrix-world.js
You can see lines like this :
App.scene[squareObject.name] = squareObject;
I have a global object App.scene . I put here all object buffer data. It is a key access but works like array.
I wanna say your idea about arrays is good. But not in parallel order. Procedural part works with no problem you need draw function for each element entity.
Look at draw methods :
https://github.com/zlatnaspirala/visualjs/blob/master/project/project_instance_webgl2/lib/matrix-draws.js
For example one of my draw entity is App.operation.draws.cube function.
I use this method to draw any cube but each cube is uniq object with uniq data inside.

Passing objects in Android that I didn't create?

I'm looking for a way of passing an object that I didn't create and cannot modify to implement parcelable in android. I was given a jar file that placed into the project by building a path to it. Now i need to pass the object created from activity to activity so that I may use the contents of the jar file. Right now it is set up so I define it as static, which probably isn't the best way. The only other option I can think of is using putSerializable but I've heard that puts strain on the system. So, what are my other options?
The main problem you have here is if that class has non-accessable private fields (through getters), then you cannot get this data to parcel it. If all private fields are accessable, then you might have several possibilities:
Extending it with a Parcelable subclass (as suggested by Simon in the comments).
Wrapping it in another Parcelable object.
Converting it to an already Parcelable object (e.g. any implementation of Map)
Note that if the object itself is not very big then the performance drop between parcelling and serializing shouldn't be noticeable. So I would go for Serializing and if the performance is not satisfactory then consider other options.

Why use parcelable when you can perform the same task using static variables?

i am new in android and java ... i am reading from couples of day about android parceling tutorial for transfer data or variables values from one activity to other or one class to other ... but i am not so understood about that.
can u tell me that is it necessary to use Parcelable for this purpose because same task can also be perform using static key word for variables as string,int or array type then why parcelable pls explain in detail ..
thanks for explanation in advance please provide comparison with example
While technically both approaches will work, there are a couple of flaws.
The first is that the static variable is static. If you have two instances of the same activity, they will both reference the same static object. This is probably not what you want.
Secondly, it's considered bad practice to access global variables. It makes it difficult to see what is going on, is difficult to test and you someone (another class) can modify your data. This creates some horrendous bugs.
By passing the data via a Parcelable object it is very clear what you are doing and you avoid both of these problems.
Note that this advice is not specific to Android, rather to Java and programming in general.
Static references never get garbage collected so you end up creating something called a memory leak.
You are keeping an object in memory that you don't need and it can't be freed up.
If you instantiate enough objects like this you will get an out of memory (oom) exception which will cause the app to crash.

Passing objects in android

I want to pass a client object to a diffrent activity on android
I know how to pass strings but have no idea about passing objects.
myIntent.putExtra("nick",nick);
where nick is a string
how do i pass an object say Client c?
"If you're just passing objects around then Parcelable was designed for this. It requires a little more effort to use than using Java's native serialization, but it's way faster (and I mean way, WAY faster)."
How to send an object from one Android Activity to another using Intents?
If the activity you are passing the object to is your own, serialize the object into a string and deserialize in the activity. http://java.sun.com/developer/technicalArticles/Programming/serialization/
Or as answered here: How to pass an object from one activity to another on Android
Think hard about whether you need to send the object or if you really just need a few data elements out of the object. Sending the primitives or Strings will likely be much simpler (= faster, potentially less buggy) if it's enough to meet your needs.
If you do need to pass an object then you could either implement the Parcelable interface or you could put the object into a static variable (of type List, Set, Map, etc.) in another class and reference it that way. There are drawbacks to these approaches and I would only recommend them if you can't get by passing the actual data values you need through the bundle.
Caveat: the standard line is use simple primitives/Strings as name:value pairs, prefer parcelable over serializable
The argument is that passing serialized objects is inefficient, so do not do it. For a small object I am not so sure that this is a real world concern. It has been argued for readability and clarity over efficiency unless you detect poor performance. So far with a small object I have not detected any performance problems. IMHO, using the fully qualified name of the class in the name:value pair and serializable objects makes the code readable, simple , less buggy, easier to maintain and is easy to implement during prototyping. If performance problems are detected, or you have time to refactor the code base, then the serializable code can be converted to Parcelable code once the object properties have stabilized.
OK. I am putting on my flame suit.

Categories

Resources