I have searched today how to make Parcelable to share some objects between activities through intent. The all examples I found are with custom objects with basic data like int/string/arraylists etc. Is there a way to make a parcelable of a MediaPlayer object ? So far I have this:
public class mpParcelable implements Parcelable {
private MediaPlayer mp;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeValue(mp);
}
public static final Parcelable.Creator<mpParcelable> CREATOR
= new Parcelable.Creator<mpParcelable>() {
public mpParcelable createFromParcel(Parcel in) {
return new mpParcelable(in);
}
public mpParcelable[] newArray(int size) {
return new mpParcelable[size];
}
};
private mpParcelable(Parcel in) {
mp = in.readValue();
}
}
The part where I don't know what todo is on setter if I can say like that: where mp = in.readValue(); I don't know how to read the MediaPlayer object.
Is there a way to make a parcelable of a MediaPlayer object ?
No, because that is not your class. Occasionally, you can create a wrapper around some other class and the wrapper can be Parcelable, but I do not see how this would work with a MediaPlayer.
IMHO, what you want (sharing a MediaPlayer between components) is a code smell. Either each component should have its own MediaPlayer, or the MediaPlayer should be centrally managed (e.g., via a service).
Related
I'm trying to use firestore recycler adapter with a parcelable class, but it needs to have an empty constructor.
My solution now is to create a regular class with an empty constructor and right after fetching the data, I'll map the objects into a parcelable copy.
But is it possible to create a Parcelable Class with an empty constructor? In Android Studio when I do right click -> Generate -> I see no secondary constructor option so I guess it's not possible, right?
Yes, it is possible. The Parcelable object will be serialized and deserialized without any problem.
In Android Studio when I do right click -> Generate -> I see no secondary constructor option so I guess it's not possible, right?
No, the fact that it doesn't appear as suggestion in Android Studio code completion feature doesn't mean it is not possible.
Taking as a reference the Parcelable implementation from Android documentation. You should then need to add an empty constructor. Just write the code, don't use code generator.
public MyParcelable(){
}
The class then should look like this:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
public MyParcelable(){
}
}
Below is the example of my Parcelable class. As you can see, I want to put activity in a Parcel, but how could I do that? I look into the source code of Activity, it is not Parcelable nor Serializable.
public class MyParcelable implements Parcelable {
private Activity mActivity;
private int mData;
private String mName;
#Override
public void writeToParcel(Parcel out, int flags) {
//out.writeX(mActivity);
out.writeInt(mData);
out.writeString(mName);
}
private MyParcelable(Parcel in) {
//mActivity = in.readX();
mData = in.readInt();
mName = in.readString();
}
public MyParcelable(Activity activity, int data, String name) {
mActivity = activity;
mData = data;
mName = name;
}
#Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
#Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
#Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
You can put anything in Parcel and take anything out of Parcel. But whether that "anything" will work afterwards will depend on variety of factors.
All Activity instances exist in close cooperation with Android's ActivityManager. Most of methods, that define Activity: startActivity(), finish(), restart(), setContentView(), getPackage() delegate to methods of ActivityManager, ViewManager, PackageManager, and other system services. These methods won't work after Activity is destroyed by system. Those methods also won't work if you instantiate Activity class without Android's "special sauce". While it is technically possible to instantiate an Activity class using reflection or JNI, those instances simple won't work.
This is what people mean, when they say that Activity is "managed by Android": it is basically driven by OS processes, and can not exist without communication with those processes. Fortunately, Android has a way to initiate such communication: an Intent. Replace this line:
private Activity mActivity;
with
private Intent mActivity;
And use the parcelized Intent to start the Activity once you receive it on other side. Of course, if you need more things than just Intent to get your Activity in usable shape, you will have to store those things alongside with Intent within your Parcelable.
This is not good idea to put activity to parcel. If you require to do this, probably your code is bad and you need to review the code to avoid this implementation.
I am new to android and am having a bit of trouble wrapping my head around the Parcelable interface.
I eventually found this:
https://stackoverflow.com/a/2141166/6647053
The point made in the above answer is that when passing an object to an activity, this:
intent.putExtra("object", parcelableObject);
performs much better than this:
intent.putExtra("object", serializableObject);
My question is:
Would there be any performance benefit to using a Parcel's read / write Serializable methods within the Parcelable (as opposed to just using a serializable object with intent.putExtra)? Why / Why not?
Example:
public class MyParcelable implements Serializable, Parcelable {
/* Some Custom Object Stuff Here */
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeSerializable(this);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel parcel) {
return parcel.readSerializable();
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
There is no benefit to writing this: parceling will be as slow as serializing.
In ordinary Java, Externalizable can perform better than Serializable, because you supply your own readExternal(ObjectInput in) and writeObject(ObjectOutput out) in which you are expected to manually serialize your fields instead of relying on the JVM to introspect and automatically do it for you. Android's Parcelable serves a similar purpose.
I know putExtra can be used to pass objects/strings around between actives. But I am trying you put an ArrayList of objects like ArrayList<Foo> in putExtra
Is this possible?
No it isn't. You'll need to serialize your object into some kind of string representation. One possible string representation is JSON, and one of the easiest ways to serialize to/from JSON in android, if you ask me, is through Google GSON.
Also 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).
From Docs :
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
You can use
intent.putParcelableArrayListExtra() for passing Arraylist in intent.
Refer to http://developer.android.com/reference/android/content/Intent.html#putParcelableArrayListExtra(java.lang.String, java.util.ArrayList)
EDIT :
one more link : Help with passing ArrayList and parcelable Activity
Only for very limited and particular types of "Foo". If i recall correctly Double and Long (or maybe it was Integer?) being those types. There might be a way to smuggle a more generic ArrayList through by encapsulating it in some Serializable Object, but I'm not sure about that.
My program has a range of different class activities (basically different screens). In one activity I am creating multiple objects which I would then like to access in other activities.
How do I go about making these objects accessible to other activities within my program, in other words how do I share objects with other activities?
TIA
Mark
The first thing you need to resolve is the operation order. If activity A is the one with the shared objects, what would you do if activity B is run without activity A ever being initialized? Do remember that intents to start activities may come from everywhere, though, to be truthful, exiting with NULL pointer dereference is an acceptable response.
What I did when such a thing was necessary was to not have the shared objects part of the activity, but create a specific object for containing those. You can then store a static reference to that object inside the object, and return it via a static method:
public class GlobalParams {
private static reference;
public static GlobalParams getReference()
{
if( reference==NULL )
reference=new GlobalParams();
return reference;
}
}
I don't think parcelable would help you, as that would create distinct copies for the different Activities to use.
Shachar
You need to have that class implement Parcelable
It's basically kinda similar to Java's serializable. You have to tell your class how to pack and unpack itself. Then you can just put it in an intent via intent.putExtra();
Here is the code example taken from that link
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}