Serializable in Intent/Bundle not working - android

I moved the Model to an external Dependency so I can reuse it on Server and other Parts. But now I'm having the Problem that when I serialize to Intents Extra and then deserialize in BroadcastReceiver the deserialized Object is not null but it's Properties have the default Values like null (for the Strings) or 0 (for int or long).
This is excerpt from the Models Class:
public class Measurement extends Event implements Serializable {
private static final long serialVersionUID = 8246754793603601250L;
/* Some other Stuff */
}
And this from Serialization:
List<Measurement> measurements = new ArrayList<Measurement>();
/* measurements get filled */
extras.putSerializable(Intents.EXTRA_MEASUREMENTS, (Serializable) measurements);
And this from Deserialization:
List<Measurement> measurements = (List<Measurement>) intent.getSerializableExtra(Intents.EXTRA_MEASUREMENTS);

All members of Measurement and members of its members (recursion) would be Serializable

Found it. Problem was that the underlying Class Event didn't implement Serializable. Looks like this got lost during Refactoring and moving to an external Dependency.
Thanks to everybody.

Related

deserialize complicated gson string

Hi I hope someone here can help me, I am working in an android app, I already serialize the following gson object
Screenshot:
the jsonobject has many subclasses like:
PreferencialaboraEstudio,Preferencialaboralarea, and more classes,
I transfer this gson object from an activity to a new activity, in order to deserialize this object I have implemented the following code in the new activity:
Intent intent = getIntent();
String Postulado = intent.getStringExtra("Postulado");//Postulado from extra is actually a gson object
Candidato candidato = gson.fromJson(Postulado, Candidato.class);
CandidatoPreferenciaLaboralEstado preflaboraledo = gson.fromJson(Postulado, CandidatoPreferenciaLaboralEstado.class);
I have the problem in CandidatoPreferenciaLaboralEstado, as you can see in the picture there are two items of this type class in the gson object, but my code only returns the first item and not the second one, is there a way to get all the items of this type "CandidatoPreferenciaLaboralEstado" from the gson?
Thank you very much for your time and assistance in this matter.
Not sure how your root model is, but you can have something like this:
public class Postulado {
private CandidatoPreferenciaLaboralEstado candidatoPreferenciaLaboralEstado;
private CandidatoSoftware candidatoSoftware;
public class CandidatoPreferenciaLaboralEstado {
private List<CandidatoPrefAttributes> candidatoAttributesList;
public class CandidatoPrefAttributes {
private Integer cveCandidato;
private Integer cveCandidatoPreferenciaLaboralEstado;
//More
}
}
public class CandidatoSoftware {
private List<CandidatoSoftwareAttributes> candidatoAttributesList;
public class CandidatoSoftwareAttributes {
private Integer cveCandidato;
private Integer cveCandidatoSoftware;
//More
}
}
}
With respective getters.
Also looks that the candidates (CandidatoPreferenciaLaboralEstado and CandidatoSoftware) and Candidate Preferences are very similar, maybe you can unify that models to one (Candidate and CandidatePrefferences) and use multiple serialized names like:
#SerializedName(value="candidatoPreferenciaLaboralEstado", alternate={"candidatoSoftware"})
Hope this can help you!

How to inject a dependency when testing an Android activity without a third-party framework?

I want to test an Android activity CommentActivity that normally constructs and uses an instance of CommentsDataSource (both are classes that I wrote).
public class CommentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
:
CommentsDataSource = new CommentsDataSource(..);
:
}
:
}
I'm willing to create MockCommentsDataSource myself and would like to avoid using a third-party mocking framework. (Why? Because I'm a teaching trying to reduce the amount of information I need to cram into the semester and the amount of software my students need to install. I've seen other posts that recommend Guice, roboguice, and Spring.)
My question is how to pass a CommentsDataSource (or MockCommentsDataSource) to the Activity. It doesn't seem practical to make them Serializable or Parcelable, which they would have to be in order to be passed in through the Intent that starts CommentActivity. While I could easily pass in a debug flag, using it would require CommentActivity to know about MockCommentsDataSource, which is really none of its business (and in a separate application):
public class CommentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
:
debugMode = getIntent().getBooleanExtra(DEBUG_MODE, false);
// Get a connection to the database.
final CommentsDataSource cds = (debugMode ?
new MockCommentsDataSource() : // Abstraction violation
new CommentsDataSource(this));
:
}
:
}
How should I inject MockCommentsDataSource into CommentActivity? FWIW, I'm using Eclipse and am developing for recent SDK versions.
One solution that occurs to me is to use the abstract factory pattern, since it would be relatively easy to make the factories serializable. Is that the best approach, given my constraints?
Here are two ideas:
Not using factory:
This will probably work only for unit tests and not for integration tests:
Create a method that returns CommentsDataSource, e.g. getCommentsDataSource()
Create a class that inherits CommentActivity
Override the getCommentsDataSource() with a method that returns MockCommentsDataSource
Test the new class
Using factory:
As you mentioned, you can change the CommentActivity code to get the CommentsDataSource from a factory method. this way you can have the mock class returned by the factory method.
Hope this helps!
I have a simple and ugly solution to offer, using a private static field to inject the dependency:
private static Client client;
and set the field value from the test using reflection:
public static void setStaticFieldValue(final Class<?> clazz,
final String name, final Object value) throws Exception {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(null, value);
}
then, in i.e. onCreate(), use that "injected" test instance if the field is set and use the regular one otherwise.
Ugly, but requires only few changes relevant to testing to the class under test.

Passing object (with multidimensional array) from intent to another

I have a simplest object, and for this I use parcelable. But this object is more complex, have multidimensional array and I really don't know how to write the parcelable methods:
public class PointSystem
{
private int point;
private boolean [] vec1;
private HashSet <Integer> hs1;
private int [][] vecMap;
}
I removed the other istance variable of the same type and the methods so the code is more readable.
I tried with serializable but I don't know how to cast from the other intent the serializable that I get to array [][].
How could I make this object parcelable? Or there're other way to pass this object to another intent?
First off, you say you try to cast the serializable you get to array[][], are you trying to pass all of the members of this object as separate extras? Why not serialize the entire PointSystem object and pass it as an extra. Then, when you try to receive it:
PointSystem p = (PointSystem) getIntent().getSerializableExtra("Extra_Name");
int[][] vecMap = p.vecMap;
A good example of using Parcelable can be found within this answer

Extending an Android Parcelable class

I have a CustomAddress class that extends the android.location.Address class that implements Parcelable.
I am trying to make my CustomAddressimplement Parcelableto but am stuck when creating my class from a parcel. What I want to when creating CustomAddressfrom a parcel is first fill in all the fields from the super class Addressand then my own fields. So I have implemented the CREATORfield:
public static final Parcelable.Creator<CustomAddress> CREATOR
= new Parcelable.Creator<CustomAddress>() {
public CustomAddress createFromParcel(Parcel in) {
return new CustomAddress(in);
}
public CustomAddress[] newArray(int size) {
return new CustomAddress[size];
}
};
But in my CustomAddress(Parcel in)creator, I can't call super(in)because it doesn't exist in android.location.Address. I can only access android.location.Address.CREATOR. So how do I fill in my fields using CREATOR?
EDIT: link to the android Address class https://developer.android.com/reference/android/location/Address.html
Here is a similar question and Mark Murphy's excellent answer: https://stackoverflow.com/a/10841502/1140682
So, in your case, you would make CustomAddress extend Address (as you already do), call the super() method in the constructor and then read your own attributes from the passed Parcel. Same has to be done (in same order) in the writeToParcel() method, of course here adding your attributes to the parcel.

Android Parcelable and Serializable

So i know it is recommended to use Parcelable instead of Serializable in android, because it is faster.
My question is: is that impossible to avoid using Serializable right?
If I have a custom object i want to serialize, let's say I have the following class definition
public class Person {
String name;
int Age;
...
....
}
Making this parcelable is easy, because the Person class contains the types parcel.write*() supports, i.e. there is parcel.writeString and parcel.writeInt
Now, what if the Person class is the following:
public class PersonTwo {
MyCustomObj customObj;
String name;
int Age;
...
....
}
How am I suppose to parcel the MyCustomObj object??
It seems I need to use serializable again? but again, I thought it is SLOW to use serializable, and seems we have no choice but to use it in this case.
I don't understand
can someone tell me how I would parcel PersonTwo in this case?
The link given by Ajay is the exact what you are looking for, how you can do it.
Well, what you can do is implement Parcelable to your CustomObject1 and create a Parcelable class for it and then you can use that Parcelable class to Parcel it inside another Parcelable class that will Parcel both the CustomObjects.
public class CustomObject1 implements Parcelable {
// parcelable code CustomObject1
}
public class CustomObject2 implements Parcelable {
private CustomObject1 obj1;
// add CustomObject1 here with getter setter
// parcelable code for CustomObject2
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(obj1, flags);
}
private void readFromParcel(Parcel in) {
obj1 = in.readParcelable(CustomObject1.class.getClassLoader());
}
............
}
You need to make MyCustomObj parcelable.
All the composite objects should also be Parcelable. In case, you want to skip an object then don't use it writeToParcel method.
I came to point where Parcelable is an issue for me.
On Android 4.3, I am getting unmarhalling exception, when passing data between
Activities as Parcelable. It works OK on Android 4.0, 4.2 or 4.4.
It should work when changed to Serializable, even though, it is slower.

Categories

Resources