Mobile development

Alex Zhukovich

Passing object by Intent


Today, I’m talking about Intents and passing data by Intent in Android development.

Short Intent overview

An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.
An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.

Read more

Sending data via Intent
We can send data via Intent only following types:

  • int, int[]
  • double, double[]
  • char, char[]
  • float, float[]
  • byte, byte[]
  • long, long[]
  • short, short[]
  • String, String[]
  • CharSequence, CharSequence[]
  • Parcelable, Parcelable[]
  • Serializable, Serializable[]
  • Bundle

When you want passing data of primitive type it’s really easy.

Intent openDetailIntent = new Intent(MainActivity.this, DetailActivity.class);
openDetailIntent.putExtra("NAME", mNameEditText.getText.toString());

But if you want to pass object you must realise Parcelable or Serializable interface for some object.

Serializable

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype’s public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class’s state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

Read more

Next source code show how to realise parcelable class:

public class Person implements Serializable {
    private String name;
    private String surname;
    private int age;

    public Person(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Parcelable

Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a non-null static field called CREATOR of a type that implements the Parcelable.Creator interface.

Read more

Next source code show how to realise parcelable class:

public class Person implements Parcelable {
    private String name;
    private String surname;
    private int age;

    protected Person(Parcel in) {
        name = in.readString();
        surname = in.readString();
        age = in.readInt();
    }

    public Person(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(surname);
        dest.writeInt(age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Which interface is better for Java and/or Android development
If we will talk about Java development better way use Serializable, because it’s a standard Java interface. But if we talk about Android development better way use the Parcelable interface, because this interface faster than Serializable and optimised for Android OS.

Example of using each of interfaces
Parcelable:

  • Put data to intent
    Person person = new Person(
            mName.getText().toString(),
            mSurname.getText().toString(),
            Integer.valueOf(mAge.getText().toString())
    );
    Intent openDetailIntent = new Intent(MainActivity.this, DetailActivity.class);
    openDetailIntent.putExtra(DetailActivity.PERSON, person);
    startActivity(openDetailIntent);
    

    In this snipped of code mName, mSurname and mAge are EditText’s. DetailActivity.PERSON it’s a sting constant (public static final String PERSON = “person”;)
  • Get data from intent
    private void loadDataFromIntent() {
        if (getIntent().getExtras() != null) {
            Person person = getIntent().getParcelableExtra(PERSON);
            if (person != null) {
                mName.setText(person.getName());
                mSurname.setText(person.getSurname());
                mAge.setText(String.valueOf(person.getAge()).toString());
            }
        }
    }
    

    In this snippet of code mName, mSurname, mAge are TextView’s.

Serializable:

  • Put data to intent
    Person person = new Person(
            mName.getText().toString(),
            mSurname.getText().toString(),
            Integer.valueOf(mAge.getText().toString())
    );
    Intent openDetailIntent = new Intent(MainActivity.this, DetailActivity.class);
    openDetailIntent.putExtra(DetailActivity.PERSON, person);
    startActivity(openDetailIntent);
    

    In this snipped of code mName, mSurname and mAge are EditText’s. DetailActivity.PERSON it’s a sting constant (public static final String PERSON = “person”;)
  • Get data from intent
    private void loadDataFromIntent() {
        if (getIntent().getExtras() != null) {
            Person person = (Person) getIntent().getSerializableExtra(PERSON);
            if (person != null) {
                mName.setText(person.getName());
                mSurname.setText(person.getSurname());
                mAge.setText(String.valueOf(person.getAge()).toString());
            }
        }
    }
    

    In this snippet of code mName, mSurname, mAge are TextView’s.

References

« »

© 2017 Mobile development. Theme by Anders Norén.