SergeyA SergeyA - 6 months ago 17
Java Question

Passing 'data source' between activities

I would like to have a generic 'Chooser' activity - one which can be provided with abstract data source, extract data from said source, present the data in a

ListView
and return the selected item back to calling activity. Something very akin to
RingtonePickerActivity
.

What I can't figure out is how to pass generic data source from one activity to another. All that I have seen so far in term of sharing data between activities is by passing data through
Intent
's extras. But that doesn't seem to work for me here, since I do not want to provide the actual data - I want to pass a reference to abstract data source, which can be queried (not unlike the
Cursor
).

The point I'd like to emphasize is that I'd like the chooser to be agnostic of the actual source of data - abstract data source would provide methods like
getNextItem
,
getItemName
,
getItemValue
. The best models of this I can think of are Cursors or Iterators - a purely abstract mechanisms of iterating over set of data.

Since all activities of the application are hosted in the same process, this should be possible? One thing I do not want to do is to have a global data source variable inside my application, for the multitude of reasons (one of them being the fact that I will be running multiple chooser activities with multiple data sources) - I want to provide the data to the activity being started at start time.

Is it possible? Am I terribly misguided? Is there a better way?

Answer

But that doesn't seem to work for me here, since I do not want to provide the actual data - I want to pass a reference to abstract data source, which can be queried (not unlike the Cursor).

Pass an extra or Uri that identifies the abstract data source. Use that information to then query that data source.

For example, suppose that the "abstract data source" is a Web service. Your activity will need to know enough about the Web service to know what sort of data comes back, simply because the activity has to have rendering rules for that data (i.e., what to show for rows in the list). But, perhaps the actual URL for the Web service varies. Pass the URL as an extra, or as the "data" of the Intent (via setData(Uri.parse(theUrlThatYouWant)). Your activity can then use something like Retrofit to retrieve the data in a background thread and use the results in the list.

Since we have no idea what your "abstract data source" is, we cannot readily help you further. In general, what you are passing to the activity is some identifier that allows the activity to look up the data source. What you use for you identifiers, and for that lookup mechanism, is up to you and may tie into what the "abstract data source" is.

You are welcome to have generic UI populated by arbitrary data sources, but those arbitrary data sources cannot be passed around via an Intent, since Intent objects are designed to be passed across process boundaries. Your primary choices are:

  1. Use inheritance and polymorphism. Have an abstract chooser activity that does most of the work, with subclasses that can obtain the data given simple identifiers.

  2. Use some in-activity UI, such as a fragment, since you are no longer limited by Intent structures and can pass around whatever is needed.