When passing an object to another Activity using Parcelable, how can I update the object and see the changes in the original Activity?



I am working on a simple texting app in Android. In my MainActivity, when the user clicks on a conversation with someone, I send over my custom Conversation object through an intent using Parcelable. That works perfectly. Problem is, if I change any fields in this object, upon returning to the MainActivity, none of my changes are shown. As far as I can tell, Parcelable merely passes a copy of the object, rather than passing the reference to it. Is there any way I can have these changes preserved across activities?

I want to continuously update the last message that was sent in the chat. There is a RecyclerView.Adapter that will update the View with the new text. This last message text is to be displayed upon returning to my Main Activity.

I cannot attach an image because I do not have enough reputation points. But my MainActivity is just a list of conversations. My ChatActivity is the actual chat screen. Here is my code:

public class ChatActivity extends AppCompatActivity implements Parcelable {
    //receive my custom Conversation object here, left out for brevity
    mConversation.setLastMessage("This is a new message.");
    mChatAdapter.notifyDataSetChanged();
}

Upon returning to my MainActivity, despite modifying the lastMessage field, no changes are shown. How can I do this? Or is there an alternative way to continuously update an object across activities?

Any help is very much appreciated, and thank you for your time. Sorry if this was a confusing question.

Answer

You can use a ViewModel to store and update your data. It allows your Activities/Fragments to watch the data for updates and coordinates its lifecycle with the lifecycles of the connected Activities/Fragments.

Create a new ViewModel class:

public class MessagesViewModel extends ViewModel{
    
    // Define the LiveData variable(s) you want to store/interact with
    private MutableLiveData<ArrayList<Message>> messageList = new MutableLiveData<>();
    
    public MessagesViewModel(){
        // Read your file here ...
        
        // Use the file's data to update the value(s) of your LiveData
        messageList.setValue(newMessageList);
    }
    
    // Create a method for your Activity/Fragment(s) to access the LiveData
    public LiveData<ArrayList<Message>> getMessageList(){
        return messageList;
    }
    
    // Create a method for your Activity/Fragment(s) to update the LiveData
    public void updateMessageList(ArrayList<Message> updatedMessageList){
        messageList.setValue(updatedMessageList);
    }
    
    // Called when all connected Activity/Fragment lifecycles have finished
    // (If necessary, here is where you can clean up any resources your ViewModel uses)
    @Override
    protected void onCleared(){
        // Save your data back to file here ...
        
        super.onCleared();
    }
}

Retrieve your ViewModel from within both of your Activities’ onCreate() methods:

// Retrieve your ViewModel
// (You may want to make this a member variable depending on where you may need to access the ViewModel from)
MessagesViewModel messagesViewModel = new ViewModelProvider(this).get(MessagesViewModel.class);

// Call observe() to receive the data as well as any updates to it
messagesViewModel.getMessageList().observe(this, new Observer<ArrayList<Message>>(){
    @Override
    public void onChanged(ArrayList<Message> messageList){
        // Do something with your data ...
    }
});

When you need to update the data from within your Activity:

// Create your updated data ...

// Update your ViewModel with the new data
messagesViewModel.updateMessageList(updatedMessageList);

You can find more information on ViewModels at https://developer.android.com/topic/libraries/architecture/viewmodel



Source: stackoverflow