Explain Codes LogoExplain Codes Logo

What's the best way to share data between activities?

java
data-sharing
persistent-data
memory-leaks
Nikita BarsukovbyNikita Barsukov·Oct 19, 2024
TLDR

To share data between activities, we can utilize Intents with 'extras'. Let's see this magic in action:

// I'm just a line of code, but with great responsibility. intent.putExtra("key", "value");

We can recall this data in the following way:

// Knock knock. Who's there? It's me! Data Recall String value = getIntent().getStringExtra("key");

For more complex objects, Parcelable is a ninja tool. Why Parcelable over Serializable, you ask? Because efficiency is always preferred:

// 'MyObject' implements Parcelable // Call me Mr. Efficient, or simply, Parcelable intent.putExtra("obj_key", new MyObject());

To extract it back:

// Extracting the genius out of Parcelable MyObject obj = getIntent().getParcelableExtra("obj_key");

Regarding retrieval methods, use them judiciously (getStringExtra, getParcelableExtra, etc.)

When it gets serious: larger data

Handling larger data feels like wrestling with a grizzly bear, but fret not, we have SQLite or files for persistent data storage at our disposal. Think of SQLite as the chess board for structured data or file storage for the wild bunch. If you are more comfortable with dealing with objects, consider using an ORM like Room.

Got tempted by static fields because of their deceptive simplicity? Beware! They can lead you into the dark realm of memory leak issues. By the wise coders, an effective antidote has been given - the static Singleton pattern. It's like having a master key that lets you in anywhere without the risk of misplacing it.

For staying updated with data changes, LiveData is your friend; it is lifecycle-aware, keeping you on top of the game when data state changes.

Sharing complex data: some strategies

The singleton pattern

Think of the Singleton as 'The Chosen One' among patterns. It sounds fancy, doesn't it?

public class DataRepository { private static DataRepository sInstance; private ComplexObjectType mData; // Born to protect you from unwanted instantiation private DataRepository() {} public static DataRepository getInstance() { if (sInstance == null) { sInstance = new DataRepository(); } return sInstance; } // It's not a gossip whisperer. It handles data exchanges discreetly public ComplexObjectType getData() { return mData; } public void setData(ComplexObjectType data) { this.mData = data; } }

To access the singleton data, use:

// No worries! Singleton guarantees that only one instance exists. DataRepository.getInstance().setData(new ComplexObjectType());

Managing state with the application context

If managing Goku's power level seems easier than managing an application context, try using your custom Application class by extending android.app.Application. Just remember, memory leaks are as stealthy as ninjas, avoid holding onto context-requiring objects.

Running away from memory leaks

WeakReferences can be likened to the rookie cop that always gets the job done - helps avoid memory leaks. This self-sacrificial data type allows the garbage collector to clean up the memory.

// Don't worry. It doesn't hold grudges against the garbage collector private WeakReference<Context> mContextRef;

Persistent data sharing methods

The lifeline of data shouldn't be shorter than the life of an application. With SharedPreferences, you can store simple key-value pairs. For more sophistication, by SQLite database or Room, you can work with structured data.

// Storing data with the elegance of a poet SharedPreferences sharedPref = getSharedPreferences("app_data", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putString("shared_key", "shared_value"); editor.apply();

Retrieving persistent data:

// Playing 'hide and seek' with Persistent Data String value = sharedPref.getString("shared_key", "default_value");

Key concepts to remember

Lifecycle-aware components

Components that honor Activity lifecycle are as loyal as the Night's Watch in Game of Thrones, like ViewModels and LiveData, reducing the risk of White Walkers (crashes due to lifecycle-related issues).

Performance optimization

Want to avoid overhead? Check out the Black Friday sale on getting rid of unnecessary getters/setters. Remember, Android passes by reference not by value (truth bomb!).

Strategy first

Each data type has its preferences for sharing methods - like that friend who insists on only using a specific app for chatting. Tune your strategy according to size, complexity, and persistence requirements.

Keep an eye on updated practices

Have you checked the Android documentation recently? Always be the first one to know about the latest performance best practices.