12/08/2018, 15:11

The common ways to pass data in the Android applications

In the Android projects, data-passing from here to there (e.g. Activity to Activity, Activity to Fragment, Fragment to Fragment) can be various which is depending on the data-types. There are several ways to do it which is summarizing below: The most common way to send data is using ...

In the Android projects, data-passing from here to there (e.g. Activity to Activity, Activity to Fragment, Fragment to Fragment) can be various which is depending on the data-types. There are several ways to do it which is summarizing below:

The most common way to send data is using Intent. Basically, we can pass data depending on the data-types. For example, if the data is primitive type ( e.g. boolean , byte , char , short , int , long , float and double ), string or user-defined objects, then we can send it as intent extras.

Sample:

To send primitive or String data from one Activity to another Activity:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("KEY_INTEGER_VALUE", 4);
intent.putExtra("KEY_DOUBLE_VALUE", 40.5);
intent.putExtra("KEY_BOOLEAN_VALUE", true);
intent.putExtra("KEY_STRING_VALUE", "String data");

Also, you can use Bundle to send multiple data via Intent as following:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("KEY_INTEGER_VALUE", 4);
bundle.putDouble("KEY_DOUBLE_VALUE", 40.5);
bundle.putBoolean("KEY_BOOLEAN_VALUE", true);
bundle.putString("KEY_STRING_VALUE", "String data");
intent.putExtra("KEY_BUNDLE_VALUE", bundle);

To receive a single data:

int value = getIntent().getExtras().getInt("KEY_INTEGER_VALUE");

As well as, you can receive multiple data/objects using Bundle:

Bundle bundle = getIntent().getExtras();
int valueInteger = bundle.getInt("KEY_INTEGER_VALUE");
double valueDouble = bundle.getDouble("KEY_DOUBLE_VALUE");
boolean booleanValue = bundle.getBoolean("KEY_BOOLEAN_VALUE");
String valueString = bundle.getString("KEY_STRING_VALUE");

The same way goes to byte, char, short, long or float.

Now, let's discuss about user-defined objects. We can make our objects either Serializable nor Parcelable.
If the object is implemented as Serializable as below:

import java.io.Serializable;

public class AnyObjectSerializable implements Serializable {
    private int mIntValue;
    private String mStringValue;

    public AnyObjectSerializable(int intValue, String stringValue) {
        mIntValue = intValue;
        mStringValue = stringValue;
    }
}

Then, you can use the following code-snap to send this object via Intent.

// initializing the object.
AnyObjectSerializable anyObjectSerializable = new AnyObjectSerializable(30, "Thirty");
// initializing the intent & bundle. 
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("KEY_ANY_OBJECT", anyObjectSerializable);  
intent.putExtra("KEY_BUNDLE_VALUE", bundle);

But, using the Serializable object prones to make a garbage collection with a lot of temporary objects. So, many developers prefer to work with Parcelable objects to get a speedy process which is usually implemented as following:

import android.os.Parcel;
import android.os.Parcelable;

public class AnyObjectParcelable implements Parcelable {
    private int mIntValue;
    private String mStringValue;

    public AnyObjectParcelable(int intValue, String stringValue) {
        mIntValue = intValue;
        mStringValue = stringValue;
    }

    protected AnyObjectParcelable(Parcel in) {
        mIntValue = in.readInt();
        mStringValue = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mIntValue);
        dest.writeString(mStringValue);
    }

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

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

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

And, you can use the following code-snap to send a Parcelable object via Intent.

// initializing the object.
AnyObjectParcelable anyObjectParcelable = new AnyObjectParcelable(30, "Thirty");
// initializing the intent & bundle. 
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("KEY_ANY_OBJECT", anyObjectParcelable);  
intent.putExtra("KEY_BUNDLE_VALUE", bundle);

Or, you can send objects without using any bundle:

AnyObjectSerializable anyObjectSerializable = new AnyObjectSerializable(30, "Thirty");
AnyObjectParcelable anyObjectParcelable = new AnyObjectParcelable(30, "Thirty");
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("KEY_SERIALIZABLE_VALUE", anyObjectSerializable);
intent.putExtra("KEY_PARCELABLE_VALUE", anyObjectParcelable);

To receive any Serializable object you can to use the following code-snap:

AnyObjectSerializable anyObject = (AnyObjectSerializable) intent.getSerializableExtra("KEY_SERIALIZABLE_VALUE");
// Or,
AnyObjectSerializable anyObject = (AnyObjectSerializable) intent.getExtras().getSerializable("KEY_SERIALIZABLE_VALUE");

To receive any Parcelable object you can to use the following code-snap:

AnyObjectParcelable anyObjectParcelable = intent.getExtras().getParcelable("KEY_PARCELABLE_VALUE");
// Or,
AnyObjectParcelable anyObjectParcelable = intent.getParcelableExtra("KEY_PARCELABLE_VALUE");

To receive any Serializable/Parcelable object using Bundle you can to use the following code-snap:

Bundle bundle = getIntent().getExtras();
AnyObjectSerializable anyObjectSerializable = (AnyObjectSerializable) bundle.getSerializable("KEY_SERIALIZABLE_VALUE");
AnyObjectParcelable anyObjectParcelable = (AnyObjectParcelable) bundle.getParcelable("KEY_PARCELABLE_VALUE");

Now, let's discuss about sending data among Fragments & Activities.

To send data from Activity to Fragment you can use the following solution:

Bundle bundle = new Bundle();
bundle.putString("KEY_STRING_VALUE", "String data");
AnyObjectParcelable anyObjectParcelable = new AnyObjectParcelable(30, "Thirty");
bundle.putParcelable("KEY_ANY_OBJECT", anyObjectParcelable);  
MyFragment fragment = new MyFragment();
fragment.setArguments(bundle);   

To receive the bundle from Activity:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String stringValue = getArguments().getString("KEY_STRING_VALUE");    
    AnyObjectParcelable anyObjectParcelable = getArguments().getParcelable("KEY_ANY_OBJECT");
    return inflater.inflate(R.layout.fragment, container, false);
}

Also, manytimes we need to pass data/objects using ArrayList, Parcelable array or maybe SparseArray . So, we can simply do as following:

/** To sent ArrayList of Serializable type data */

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
ArrayList<AnyObjectSerializable> anyObjectListSend = new ArrayList<>();   
intent.putExtra("KEY_BUNDLE_VALUE", bundle);

/** To receive  ArrayList of Serializable type data */
ArrayList<AnyObjectSerializable> anyObjectListReceive = (ArrayList<AnyObjectSerializable>) intent.getExtras().getSerializable("KEY_VALUE");
/** To sent Parcelable type data */

// a)  ArrayList of objects.
// using bundle 
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
ArrayList<AnyObjectParcelable> anyObjectList = new ArrayList<>();   
bundle.putParcelableArrayList("KEY_VALUE", anyObjectList);
intent.putExtra("KEY_BUNDLE_VALUE", bundle);

// Or, using directly via intent
intent.putParcelableArrayListExtra("KEY_VALUE", anyObjectList);

// b)  Parcelable[] data using bundle 
Parcelable[] parcelablesSend = new Parcelable[] { new Bundle() };
bundle.putParcelableArray("KEY_VALUE", parcelablesSend);

// c) SparseArray<Parcelable> data using bundle 
SparseArray<Parcelable> sparseArray = new SparseArray<>();
bundle.putSparseParcelableArray("KEY_VALUE", sparseArray);

/** To receive Parcelable type data */

// a)  ArrayList of objects.
ArrayList<AnyObjectParcelable> anyObjectList = getIntent().getExtras().getParcelableArrayList("KEY_VALUE");
// b)  Parcelable[] data using bundle 
Parcelable[] parcelablesReceive = getIntent().getExtras().getParcelableArray("KEY_VALUE");
// c) SparseArray<Parcelable> data using bundle 
SparseArray<Parcelable> sparseArray = intent.getExtras().getSparseParcelableArray("KEY_VALUE");

This is how, you can pass data with or without bundle via Intent among Activites & Fragments.

Here, "coupling" means you can pass data by using static/non-static fields, getter or setter properties among activities & fragments. This is a basic way to pass data which depends on the memory of the same process.

Sample:

public class MyData {
    // static fields
    public static String sName = "my_name";
    public static int sAge = 27;
    
    // non-static field
    private double mScore = 4.5;
    
    // constructor with parameter
    public MyData(double score) {
        mScore = score;
    }

    // empty constructor
    public MyData() {

    }

    // getter for non-static field
    public double getScore() {
        return mScore;
    }
    
    // setter for non-static field
    public void setScore(double score) {
        mScore = score;
    }
}

To pass the data you need to write code as below:

/** you can access static fields without creating any instance */
String name = MyData.sName;  
int age = MyData.sAge;

/** But, you can set/get non-static fields after creating a instance of the class */
MyData myData = new MyData();
myData.setScore(9.5);
myData.getScore();

/** You can pass data through the constructor */
MyData myData = new MyData(5.5);

Moreover, You can make a singleton class as following:

public class MyData {
    private String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        data = data;
    }

    private static final MyData sMyData = new MyData();    

    public static MyData getInstance() {  
        return sMyData;
    }
}

And, access as following: String data = MyData.getInstance().getData();

Overall, it depends on your written code about how you want to pass you data.

Another common way is saving data/object into disk & retrieving it whenever you need. There are few ways to do it, for example:

  • HashMap of WeakReferences - See more
  • Shared Preferences - See more
  • Sqlite Database - See more
  • Save data to a file - See more

You can choose an advantageous way to pass the data based on the requirement or situation. Happy coding!

0