-1

I would like to know what is the proper way to access non-primitive data between activities. Although there are many questions and answers on the topic, I still think that my question hasn't been asked yet.

1) The main activity shows a custom adapter ToDoListAdapter. ToDoManagerActivity loads data for entries in its methods loadItems() and saveItems() in onPause() and onResume():

public class ToDoManagerActivity extends ListActivity {
    toDoListAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new ToDoListAdapter(ToDoManagerActivity.this);
        .....
    }
}

2) Another activity TodoChartActivity is fired from ToDoListAdapter view and is an activity that shows all entries, but differently. In order to show the entries, I need the data that is in adapter variable in main activity.

According to sources in the internet, there are different ways to make adapter variable (or any other) accessible in the second activity:

  1. Make mAdapter public and static or make public getter&setter for it. BAD APPROACH
  2. Access it from Application Singleton. BAD APPROACH
  3. Copy loadItems() and saveItems() from ToDoManagerActivity and load them again into memory. Since I use memory much more that I actually need -- BAD APPROACH
  4. Passing all data of one list entry through intent extras. TEDIOUS APPROACH, I was told. Also, let's imagine, that we need all entries, for example. So, it's a general question.

Do you have other suggestions, how to access complex objects and lists between activities?

Community
  • 1
  • 1
soshial
  • 5,906
  • 6
  • 32
  • 40
  • The name of `EditTodoActivity` indicates you are working with a single todo item so why not just pass it's id and have the `EditTodoActivity` load the relevant details. Or in other words why are you trying to pass the adapter? – Cory Charlton Feb 12 '16 at 23:57
  • @soshial, you can always pass the data from `ToDoManagerActivity` to `EditToDoActivity` via an Intent. If you want to pass custom objects, make sure they implement the `Parcelable` interface. – chaitanya Feb 13 '16 at 00:01
  • I am aware, that it's possible to pass data of one ToDoItem through intent extras, but I wonder **in general**. Imagine, that every list entry were too big for passing it like that. Also, that is a bit tedious to put and extract extras each time. – soshial Feb 13 '16 at 00:01
  • @soshial That is why you pass an ID like Cory said and then extract the relevant data. If you only want to load the data once, then you are kind of stuck with the Bad Approaches you mentioned in the original question – chaitanya Feb 13 '16 at 00:03
  • @chaitanya, if I pass just an id to the second activity, then where do I take all data from. In order to do that, I need to load ALL DATA in the 2nd activity into memory again, which is not a good thing memory-wise. That is why accessing mAdapter variable seems better choice, Considering all said, what do you think? – soshial Feb 13 '16 at 00:07
  • @soshial it is a very common thing to do in Android Apps. That is why you only load the data which you need. e.g. If you are only showing Name of the ToDoActivity, just load the name and id of it and then fetch the records as necessary. Alternatively check this out http://stackoverflow.com/questions/5854791/android-how-to-implement-parcelable-to-my-objects and see whether you want to do something like that. You only would have to make a few get calls – chaitanya Feb 13 '16 at 00:10
  • @chaitanya, I changed the purpose of the second activity in my question. What if I needed ALL data (not only one entry as you suggest)? – soshial Feb 13 '16 at 00:16
  • @soshial then load it again or use one of your "bad approaches". The link in #2 doesn't actually represent a singleton which would be the approach I would likely use if I had so much data that retrieving it twice would exceed memory limits. – Cory Charlton Feb 13 '16 at 00:22
  • The key of course would be smart about it. For instance you have a `DataSingleton` static instanced with a `getItem(int itemId)` method. In the `getItem(int itemId)` method you should ensure that your backing List has been loaded and do so if not. Or simply initialize the data in the constructor. – Cory Charlton Feb 13 '16 at 00:27
  • @soshial see whether this link http://developer.android.com/training/basics/fragments/communicating.html fits what you want to do. I guess have a getter method in the interface and pass the interface object around – chaitanya Feb 13 '16 at 00:43

2 Answers2

0

ToDoManagerActivity is your first Activity, from here you are initiating ToDoListAdapter and from ToDoListAdapter you are inflating TodoChartActivity.

This is a common scenario. Since, your data is same, just share it across the adapters.

From ToDoManagerActivity pass the list of object in your ToDoListAdapter. Now, you have your data in this adapter. Now, pass the same data to TodoChartActivity.

Ritt
  • 3,181
  • 3
  • 22
  • 51
  • My exact question was: **HOW**. Also, I don't inflate TodoChartActivity in my adapter. Also, I have only one adapter, while you state that there are several of them. – soshial Feb 14 '16 at 23:03
0

A singleton is not necessarily a bad approach unless the lifetime of its contents is being held longer than they're used by the two activities. You could even put the container object in a WeakReference so that it's garbage collected after the two activities using the data are no longer around and holding references to the data. The major downside to this approach is that your activities can't save and retain they state if they need to be destroyed and recreated.

You could also persist your data to a sqlite database. If you don't want to break out all the fields from all your objects into sqlite fields, you could "cheat" and just serialize them as JSON with something like Gson that will automate this process if your model data can be represented as Java primitive types and basic collections. If you do this, then your activities can also rebuild themselves from the data persisted in sqlite in case they are destroyed by Android. The downside is that you now have to figure out when to remove this data from the DB when it's no longer being used. And if you need to use this scheme more than once at a time in your app, you need to be able to identify each collection of data using some id and make sure that id is shared between activities.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441