1

My MainActivity calls another Activity A which needs to access some members of MainActivity. What is the best way to send a reference to Main Activity (or its context) to Activity A without resorting to complicated methods like parcelables etc?

There are some heavyweight android wrestling matches here but I am not sure that it is relevant to my problem.

details

I have Alert and Alerted objects in a one-to-many relationship (Alerted represents the various times an Alert was rung).

AlertsListActivity extends ListActivity which displays a list of Alert objects from a SQLite database table (primary key: alertId). It has an AlertsListAdapter.

AlertedsListActivity has a ListFragment which displays a list of Alerted objects from Alerted table (foreign key is alertId from Alert table). It has an AlertedsListAdapter.

AlertsListActivity needs to call AlertedsListActivity to display the list of Alerted objects. I used startActivityForResult().

Inside AlertedsListAdapter

    public View getView(int position, View convertView, ViewGroup parent) {
        final Alert alertItem = (Alert) mainActivity.alertsListAdapter.getItem(position);
        final Alerted alertedItem = (Alerted) getItem(position);
...

I do need the Alert objects also, in order to display some identifying information from them with each Alerted list item. Hence I need the reference to mainActivity.alertsListAdapter

How can AlertedsListActivity access AlertsListActivity?

Update: Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.

This allows the data to be accessed from Activity A.

Community
  • 1
  • 1
likejudo
  • 3,396
  • 6
  • 52
  • 107
  • 1
    What are the members of MainActivity that Activity A needs access to? – Mike M. Mar 30 '14 at 01:11
  • The Adapter itself, or the underlying data? Perhaps if you could edit your question to more fully explain your goal, we could give you "safer" ideas than passing around Activity Contexts. – Mike M. Mar 30 '14 at 01:20
  • It appears that all you need in AlertedsListActivity is the alertId. Simply use the `putExtra()` method of the Intent object you're using in `startActivityForResult()` to pass it to AlertedsListActivity. – Mike M. Mar 30 '14 at 01:53
  • I do need the Alert objects also, in order to display some identifying information from them with each Alerted list item. Hence I need the reference to `mainActivity.alertsListAdapter` – likejudo Mar 30 '14 at 02:13
  • 1
    You can use the `putExtra()` method to attach more than one (primitive) extra to the Intent; essentially, as many as you'd like. Alternatively, you could pass an `Alert` object, but your `Alert` class would need to implement `Serializable` or `Parcelable`. You really don't wanna do what you're trying to do. – Mike M. Mar 30 '14 at 02:19
  • Alert does implement Parcelable and has several fields so it will not be good to send several alerts in this way. Hence I think it is better to pass in a reference to the list adapter so that the Alerts can be referenced whilst maintaining their 1:n relationship to Alerteds. Perhaps I shall create a singleton out of the AlertsListAdapter – likejudo Mar 30 '14 at 02:56

2 Answers2

2

Here's the simple, common way to do it:

singletons typically have variables like the below example, "useThisContext" or "mainFeedIsHere".

public class Cloud
    {
    private static Cloud ourInstance = new Cloud();
    private Cloud() { Utils.Log("cloud singleton launched"); }
    public synchronized static Cloud getInstance()
        {
        return ourInstance;
        }

    /////////////////////////////////////////////////

    public Context useThisContext;

another example ...

public class Feed
    {
    private static Feed ourInstance = new Feed();

    private Feed()
        {
        Utils.Log("feed singleton launched");
        freshestPostsForDisplay = new ArrayList<ParseObject>();
        }

    public synchronized static Feed getInstance()
        {
        return ourInstance;
        }

    public List<ParseObject> freshestPosts;
    public MainActivity mainFeedIsHere;

Quite simply when everything launches (or when it changes), those "things" need to set those variables in the singleton. In other words, those things "tell the singleton, where they are." It's that simple.

So, in the MainActivity perhaps, in onCreate, it might say something like...

    CLOUD.useThisContext = this;
    FEED.mainFeedIsHere = this;

Then for example inside Feed.java you may have say

mainFeedIsHere.feedReload();

It goes without saying you have to check that they are not null (but how else could it be?) and you have to keep them up-to-date as it were. (i.e., for whatever reason you may want to change "useThisContext" -- again how else could it be?)

{Sometimes you'll have one "centralised" singleton .. perhaps "State" .. to sort of combine all these together - so that anyone can "get to" any of those "exposed" things as needed. This is, really, how game engines go; so that you can say more or less SoundEffects.Booms() or Tanks.Faster() or AI.FindVillains() at any time anywhere.}

Cheers!

Fattie
  • 27,874
  • 70
  • 431
  • 719
0

Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.

This allows the data to be accessed from Activity A.

likejudo
  • 3,396
  • 6
  • 52
  • 107