Android, how to send array[] of my own classes via Intens - java

I have problem with starting new Activity in my app.In shorthand it will be app of sound effects(animals,people,fun...)
In my MainActivity there is button with onClick method
public void clic(View v) {
Intent newIntent=new Intent(this,AktivityImage.class);
newIntent.putExtra("id", aFactory.getAnimals());
startActivity(newIntent);
}
Method aFactory.getAnimals() returns array of my own class:
public Entit[] getAnimals(){
return aArrayAnimals;
}
Class Entit is primitive, just constructor and 2 getters.
import java.io.Serializable;
public class Entit implements Serializable{
private int aSound;
private int aImage;
public Entit(int paIdImage,int paIdSound){
aImage=paIdImage;
aSound=paIdSound;
}
public int getImage(){
return aImage;
}
public int getSound(){
return aSound;
}
}
And there is a problem, in class AktivityImage
private Entit[] aEntity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sounds_layout);
aIntent=this.getIntent();
aEntity=(Entit[]) aIntent.getSerializableExtra("id");
Some tips? Thanks to all.

Like others have explained you could use Pacelable or Serializable both works the same way except in case of Bundle api. Bundle accept serializable and parcelable objects + it accepts parcelable array/arraylist/SparseArray but it doest accept array of serilaizable object as it is. Easiest way is create a Transport class ( again serializable ) some what like
public static class Transport implements Serializable{
public Entit[] data;
public Transport(Entit[] data) {
this.data = data;
}
}
And the modify make an instance of the Transport class and put it in the bundle
Intent newIntent=new Intent(this,AktivityImage.class);
newIntent.putExtra("id", new Transport(aFactory.getAnimals()));
startActivity(newIntent);
And when you read read as a Serializable casted into Transport and takeout the actual data
aIntent=this.getIntent();
aEntity=((Transport) aIntent.getSerializableExtra("id")).data;

If you'd like to pass an object through intents, they should implement the Parcelable interface. Here's the relevant doc. With your class, it should be very simple - all you have is two integers, which fit directly into a parcel without any extra work.
Any object that implements Parcelable can be placed into a bundle (and therefor also placed inside an Intent). Use one of the various getter/setter methods in Intent to set and retrieve your data.

If your class is going to be that simple, and you have a fixed number of Sound Effects then you might want to use Enums instead since Enums are automatically serializable and they can be stored in Intents and Bundles with overwhelming ease.
enum SoundEffects {PIANO, DRUM, ....}
SoundEffects mSound = SoundEffects.DRUM;
Intent intent = new Intent();
intent.putExtra("Sound", mSound);
Bundle bundle = new Bundle();
bundle.putSerializable("Sound", mSound);
and there you go.
Also, primitives like ints and doubles can be passed into Enums and Enums can have getters and setters so that won't be a problem... so using the previous example you could do
enum SoundEffects {PIANO(10, 20), DRUM(25,30), ....}
but then you have to add an constructor to your enum to accept these values.

Throught : http://developer.android.com/reference/android/content/Intent.html
you can use putExtras and getExtras respectively from sender to receiver. Extras can range from int[] to Serializables.

Related

How to pass data from one android activity to an Java class?

MainActivity(Activity)
String emailid=e1.getText().toString();
Intent i = new Intent(MainActivity.this,LongOperation.class);
i.putExtra("emailid",emailid);
LongOperation(Java class )
Intent i = getIntent();
a = i.getStringExtra("emailid");
ERROR MESSAGE:
'getIntent(java.lang.String)' is deprecated as of API 15: Android
4.0.3 (IceCreamSandwich)
In 1st Class:
Intent i = new Intent(MainActivity.this, LongOperation.class);
i.putExtra("emailid", emailid);
startActivity(i);
In 2nd Class:
Intent i = getIntent();
String emailid= i.getStringExtra("emailid");
Intents are used to pass data from one activity to another activity.
So if you want to pass data to a normal Java class i would suggest you to use a getter function in combination with a static java class.
So LongOperation has to look like that:
public class LongOperation {
private static String eMailID;
// gives the variable eMailID in this class the new value mailID
public static void setMailID(String mailID) {
eMailID = mailID;
}
// add additional code here
}
In the MainActivity you have to do sth like:
String emailid = e1.getText().toString();
// set the variable in the LongOperation class
LongOperation.setMailID(emailid);
I hope I got your question right, there are several other ways but that depends on the structure and logic of your code.
In general I would recommend to work not so much witch static, more object orientated. But in this case static might be easier.
Cheers

How Parcelable view member of object?

I have an object with a View member. So i want to pass an ArrayList of this object and i need to pass this View. I know how to implement Parcelable.
The code is something like this :
public class Variable implements Parcelable {
public View mView;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(mView)
}
public static final Parcelable.Creator<Variable> CREATOR
= new Parcelable.Creator<Variable>() {
public Variable createFromParcel(Parcel in) {
return new Variable(in);
}
public Variable[] newArray(int size) {
return new Variable[size];
}
};
private Variable(Parcel in) {
mView= (View) in.readValue(getClass().getClassLoader());
}
So I tried object method for the writeToParcel and Variable(Parcel in) methods but obviously it didn't work.
How I should do this ?
You should only implement parcelable for data objects and never for Views, the idea is to parcel/unparcel the data state to re-instantiate a given View with state.
You should also note that there is a hard set limit on the size of the buffer that a transaction can hold when you parcel your data and send it via Intent. So ideally avoid having large in-memory object being transferred via parcel (one bad example is lets say Bitmaps)
Also, implementing parcelable by hand is pretty tedious and could be error prone. I recommend using Studio's plugin or any good third party plugin for implementing Parcelable.
Hope it helps

Proper way to create an new parcelable object

I have a class model called "Car".
If I want to create a new object of "Car" I can do something like this:
Car car = new Car();
But now, I made this class implements Parcelable. What is the best way of creating a new object of the class "Car"?
Right now I am doing this way:
Car car = new Car("blue");
And I am adding a new constructor to my model Class:
public class Car implements Parcelable {
public String color;
#Override
public int describeContents() { return 0; }
#Override
public void writeToParcel(Parcel dest, int flags) { dest.writeString(color); }
public static final Creator<Car> CREATOR = new Creator<Car>() {
public Car createFromParcel(Parcel in) { return new Car(in); }
public Car[] newArray(int size) { return new Car[size]; }
};
private Car(Parcel in) { color = in.readString(); }
public Car(String myColor) { color = myColor; }
}
Since I am new to this class Parcelable I'm not sure if this is the best aproach. Is anything bad having two constructors in my class? Is there any other more efficient way to do this?
I am afraid that adding this second constructor my application should lose some performance in creating new objects of this class.
Since I am new to this class Parcelable I'm not sure if this is the best aproach. Is anything bad having two constructors in my class? Is there any other more efficient way to do this?
It depends what you need, but your implementation of parcelable patters seems to be okey.
If u need to pass efficiently your object throught intent or arguments bundle, it is best approach. Parcelable is android more efficient implementation of class serialization.
If you want little less optimal (but easier) you could use serializable, this is default java approch, it's a bit slower, and has its own drawbacks ^^.
And if more important for you is readability of generated state (parcelable and serializable will make a byte stream from your object), you might want to use Json convertion (and for that i would suggest gson.
I am afraid that adding this second constructor my application should lose some performance in creating new objects of this class.
There is nothing wrong with multiple constructors. They are simply, a way to initialize your object state. Nothing more nothing less.
PS: For your old method of creating a car to work:
Car car = new Car();
Simply add empty constructor:
public Car() { }
Cheers.

Android Context not serializable dilemma for class that implements Iteratable

Here is my situation. I have written a Playlist class that stores a context. Playlist has 9 child classes. Unfortunately, to pass Playlist between intents, it must implement Serializable. This is a problem because Playlist stores a context, so that the Iterator can work, as the Iterator method that must be Overridden from Iterator can not accept any parameters. Therefore, I must store Context somewhere as it is needed to determine the size of the Playlist. Here is the (simplified) code.
public abstract class Playlist implements Serializable, Iterable<Song>
{
private static final long serialVersionUID = 0L;
private Context context;
public Context getContext() { return context; }
public Playlist(Context context)
{
this.context = context;
}
public abstract int size(); //getContext() referenced in all currently written children
public abstract Song getSong(int index); //getContext() referenced in all currently written children
#Override
public PlaylistIterator iterator()
{
return new PlaylistIterator();
}
public class PlaylistIterator implements Iterator<Song>
{
private int current;
PlaylistIterator()
{
current = 0;
}
#Override
public boolean hasNext()
{
return current < size(); //SIZE HERE needs access to a context, but this method certainly can not take one, and neither can the constructor above.**
}
#Override
public Song next()
{
if (!hasNext())
throw new NoSuchElementException();
return getSong(current++);
}
#Override
public void remove()
{
throw new UnsupportedOperationException();
}
}
}
I have read that you can store a static context, but that this is poor design. I can not seem to find a way around this.
I have considered adding a static context reference that is assigned in writeObject, and then accessed in readObject, as the transition should be nearly instant because the Serialization implementation is only so that Playlist can be passed in an intent. But even this feels hacky.
Is there a common work around to dealing with the fact that we cannot serialize context? Is my solution acceptable in terms of stability? It might be against the rules, but what is your recommendation in this situation?
I have written a Playlist class that stores a context
That's probably not a good idea.
Unfortunately, to pass Playlist between intents, it must implement Serializable
It could be Parcelable, but that does not solve your problem. A Context cannot go into either a Serializable or a Parcelable.
because Playlist stores a context, so that the Iterator can work,
That's probably not a good idea.
Therefore, I must store Context somewhere as it is needed to determine the size of the Playlist.
Or, the Playlist could hold the size of the playlist. An int is readily able to be used with Serializable or Parcelable.
Or, get rid of the Iterator, as that is not going to work well with Serializable or Parcelable either.
I can not seem to find a way around this.
Have Playlist be a pure model object, with no Context.
Or, depending on the use case, have Playlist be a singleton, using the Application as the Context. It is unclear whether there is only one Playlist or several.
but what is your recommendation in this situation?
Playlist should not hold a Context and should not have an Iterator.

How to use setters and getters to pass data between classes in android

I'm writing a program that has two classes, one that extends Activity and another that extends SurfaceView. The activity has an object of the SurfaceView class. I am trying to use setters and getters to send data between these two classes, but every time I try, eclipse says that the methods for setting and getting need to be static. I can't do this because I don't want them to be static.
The Activity class contains the following methods:
public float getxTouch(){
return xTouch;
}
public float getyTouch(){
return yTouch;
}
The SufaceView class contains the following code:
xpos = ActivityClass.getxTouch();
ypos = ActivityClass.getyTouch();
How might I fix this without making the methods static?
You can use Intents to transfer references of variables between your Activity and your class.
First, let's create a serializable class that will contain your variables:
class XYTouch implements Serializable{
public static final String EXTRA = "com.your.package.XYTOUCH_EXTRA";
private float xTouch;
public void setX(String x) {
this.xTouch = x;
}
public String getX() {
return xTouch;
}
// do the same for yTouch
}
Then, in your activity's onCreate, create a new XYTouch object and set its xTouch and yTouch attributes using set and get methods. Then write
Intent intent = new Intent(this, OtherClass.class);
intent.putExtra(XYTouch.EXTRA, xytouchobject);
startActivity(intent);
In your other class (OtherClass) in which you want access to those variables:
public void onCreate(Bundle savedInstance){
// ....
XYTouch xytouch = (XYTouch) getIntent().getSerializableExtra(XYTouch.EXTRA);
// ....
}
Then, you can use get and set methods of XYTouch anywhere in your class to have a reference to xTouch and yTouch.
Another way would be to retrieve it from a class of your own that extends Application and keeps a reference to those variables. Then you would use an Activity context to read them in.
Pass the reference of the activity class to your surface class. Do something like this, so you don't have to make the methods static.
In your SurfaceView class:
Activity foo;
//some method to set foo:
public void setFoo(Activity foo) {
this.foo = foo;
}
// Then you can simple call your getX() and getY() methods like this:
foo.getX(); and foo.getY();
From your Activity class:
yourSurfaceViewInstance.setFoo(this);

Categories

Resources