0

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:

1. Sending data using Intent

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.

2. Passing data by "coupling"

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.

3. Passing data by persisting data into disk

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

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


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí