Passing complicated datastructures from one activity to another

2118 views
Skip to first unread message

trickydicky

unread,
Jan 8, 2008, 3:55:44 PM1/8/08
to Android Developers
Anybody knows if it is posible to pass complicated data structures
from one activity to another?

I'll explain my situation: I am parsing a quite complicated xml into
some beans in a screen with a "please wait message". If the loading
process is ready, I want to pass these beans to another activity to do
something with the bean content. I read that I have to this with a
Bundle, but the bundle doesn't allow user defined beans or at least I
don't know how to do it (only setString, setIntArray, etc.).

I also have read that I should do long processes in a service. Ok, but
in that situation again I should be able to pass my beans from the
service to an activity.

Anybody knows?

David Welton

unread,
Jan 8, 2008, 4:32:17 PM1/8/08
to android-d...@googlegroups.com
> Anybody knows if it is posible to pass complicated data structures
> from one activity to another?

Well... it appears it's possible to write code that lets you marshal
your complicated data structures, but it looks like something of a
pain, and might not even really let you do what you need unless you
simply wedge the whole thing into a screen.

I'm having some difficulties with this myself, with Hecl. I have an
interpreter that I'd like to pass around in order to not have to
create a new one for each activity. Furthermore, the interpreter is
not something that ought to disappear when the activity gets frozen:-/

--
David N. Welton

http://www.welton.it/davidw/

http://www.dedasys.com/

hackbod

unread,
Jan 8, 2008, 5:39:53 PM1/8/08
to Android Developers
For situations where you know the activities are running in the same
process, you can just share data through globals. For example, you
could have a global HashMap<String, WeakReference<MyInterpreterState>>
and when you make a new MyInterpreterState come up with a unique name
for it and put it in the hash map; to send that state to another
activity, simply put the unique name into the hash map and when the
second activity is started it can retrieve the MyInterpreterState from
the hash map with the name it receives.

Wink Saville

unread,
Jan 8, 2008, 6:49:08 PM1/8/08
to android-d...@googlegroups.com
hackbod wrote:
> For situations where you know the activities are running in the same
> process, you can just share data through globals. For example, you
> could have a global HashMap<String, WeakReference<MyInterpreterState>>
> and when you make a new MyInterpreterState come up with a unique name
> for it and put it in the hash map; to send that state to another
> activity, simply put the unique name into the hash map and when the
> second activity is started it can retrieve the MyInterpreterState from
> the hash map with the name it receives.
>
>
Overall that doesn't seem like a good idea to use globals,
what if they are not in the same process, what is your advice?

hackbod

unread,
Jan 8, 2008, 7:22:29 PM1/8/08
to Android Developers
On Jan 8, 3:49 pm, Wink Saville <w...@saville.com> wrote:
> Overall that doesn't seem like a good idea to use globals,
> what if they are not in the same process, what is your advice?

If you are launching activities through explicit intents (saying the
exact component to run), then you know exactly what is happening, can
ensure they are running in the same process, and all is well.

If you are using implicit intents (so other applications can be run
instead of yours), then yes globals won't work. But it's more than
that -- the activity being launched may not even be a part of your
package, so wouldn't even know what to do with any special type that
you put in the intent. So in general, if you are passing custom
complex types in intents, you are probably using activities that are
specific to your own package, so will always be running in that
process, and sharing globals is fine.

Btw, to address the original question, this all applies to
communicating with services as well. If you are using an explicit
intent to interact with your service, then you have complete control
over the process the service runs in, and can know that it will run in
your own process and make many assumptions about how you interact with
it -- going so far as to take the IBinder returned to you and cast it
to some concrete class that is part of the service. Doing this of
course ties your implementation to running in your own process, but I
think for many cases of app development this is completely fine and
worth it if it makes things a lot easier. Not everything needs to be
completely replaceable. :)

Wink Saville

unread,
Jan 8, 2008, 7:55:34 PM1/8/08
to android-d...@googlegroups.com
Isn't it true that each Activity and Service runs in
its own thread? if so I think appropriate synchronization
primitives must be used.

Also, please correct me if I'm wrong, if the
android.os.Message/Handler is used as the communication
technique then there are no issues with multi-threading
as only one message at a time will ever "handled".

So the OP may still need or want to run in different
processes, do you have any advice on how this may be
done?

Regards,

Wink Saville

hackbod

unread,
Jan 8, 2008, 8:06:55 PM1/8/08
to Android Developers
On Jan 8, 4:55 pm, Wink Saville <w...@saville.com> wrote:
> Isn't it true that each Activity and Service runs in
> its own thread? if so I think appropriate synchronization
> primitives must be used.

No, that's not true. For activities, services, and intent receivers
running in the same process, all calls from the system come on the
same thread (the main thread of the process). This is very deliberate
so that developers don't need to worry about threading issues unless
they are doing more advanced things.

> Also, please correct me if I'm wrong, if the
> android.os.Message/Handler is used as the communication
> technique then there are no issues with multi-threading
> as only one message at a time will ever "handled".

That is true. In fact this is the mechanism used by the OS underneath
to ensure that calls are made on the main thread.

> So the OP may still need or want to run in different
> processes, do you have any advice on how this may be
> done?

If you want to run in different processes, then you just have to deal
with marshalling data across processes. There are a large number of
things you can put into a Bundle, including other Bundle objects, so
worst case you can represent all of the data as Bundle maps and let
that go across. There is an issue in the current SDK where you can't
place custom Parcelable objects inside of a Bundle (you can only use
Parcelables that are part of the framework); this will be fixed in a
future SDK. We may also be supporting any Serializable object in a
Bundle, but serialization is very heavy-weight and so something to
avoid for IPC, especially on mobile devices.

Wink Saville

unread,
Jan 8, 2008, 9:35:12 PM1/8/08
to android-d...@googlegroups.com
hackbod wrote:
> On Jan 8, 4:55 pm, Wink Saville <w...@saville.com> wrote:
>
>> Isn't it true that each Activity and Service runs in
>> its own thread? if so I think appropriate synchronization
>> primitives must be used.
>>
>
> No, that's not true. For activities, services, and intent receivers
> running in the same process, all calls from the system come on the
> same thread (the main thread of the process). This is very deliberate
> so that developers don't need to worry about threading issues unless
> they are doing more advanced things.
>
>
Good information, I hadn't realized that. I've looked at the
documentation again and the documentation for Activity
doesn't say that. But the documentation for Service is
http://code.google.com/android/reference/android/app/Service.html
very clear:

"Note that services, like other application objects, run
in the main thread of their hosting process"

Although I don't see a list of "application objects" except an off
handed mention at
http://code.google.com/android/reference/android/os/Handler.html
where it says:

"When a process is created for your application, its main thread is
dedicated to running a message queue that takes care of managing
the top-level application objects (activities, intent receivers, etc) and
any windows they create."

It would be nice if we this was somewhat more explicit.

BUT, I also some conflicting information:

In rereading "Lifecyle of an Android Application" here
http://code.google.com/android/intro/lifecycle.html
it mentions 5 "processes": foreground, visible, service, background & empty.
In this context I would assume a "process" was a separate address
space, but at least a separate thread.

Then, in the documentation for Activity the "Process Lifecycle" section of
http://code.google.com/android/reference/android/app/Activity.html
talks about 3 "activities" and 1 process: foreground, visible,
background & empty,
(Note: Service is missing, is the a documentation error or is "Process
Lifecycle"
different from an Application Lifecycle?)

Anyway, here it says "The system will kill less important processes..."
which
implies to me that they are each a "activity/process" is a linux
process (i.e. a different address space).

So now I'm really confused, hopefully you can set me straight.

Thanks,

Wink Saville

Ivan.V...@gmail.com

unread,
Jan 10, 2008, 7:29:54 AM1/10/08
to Android Developers
IMHO system will kill processes without services at first place. Then
it may kill processes with services. It makes sense to run services in
standalone process in order to survive :)
--
Regards,
Ivan

On Jan 9, 5:35 am, Wink Saville <w...@saville.com> wrote:
> hackbod wrote:
> > On Jan 8, 4:55 pm, Wink Saville <w...@saville.com> wrote:
>
> >> Isn't it true that each Activity and Service runs in
> >> its own thread? if so I think appropriate synchronization
> >> primitives must be used.
>
> > No, that's not true. For activities, services, and intent receivers
> > running in the same process, all calls from the system come on the
> > same thread (the main thread of the process). This is very deliberate
> > so that developers don't need to worry about threading issues unless
> > they are doing more advanced things.
>
> Good information, I hadn't realized that. I've looked at the
> documentation again and the documentation for Activity
> doesn't say that. But the documentation for Service ishttp://code.google.com/android/reference/android/app/Service.html
> very clear:
>
> "Note that services, like other application objects, run
> in the main thread of their hosting process"
>
> Although I don't see a list of "application objects" except an off
> handed mention athttp://code.google.com/android/reference/android/os/Handler.html
> where it says:
>
> "When a process is created for your application, its main thread is
> dedicated to running a message queue that takes care of managing
> the top-level application objects (activities, intent receivers, etc) and
> any windows they create."
>
> It would be nice if we this was somewhat more explicit.
>
> BUT, I also some conflicting information:
>
> In rereading "Lifecyle of an Android Application" herehttp://code.google.com/android/intro/lifecycle.html
> it mentions 5 "processes": foreground, visible, service, background & empty.
> In this context I would assume a "process" was a separate address
> space, but at least a separate thread.
>
> Then, in the documentation for Activity the "Process Lifecycle" section ofhttp://code.google.com/android/reference/android/app/Activity.html

hackbod

unread,
Jan 10, 2008, 3:50:10 PM1/10/08
to Android Developers
On Jan 8, 6:35 pm, Wink Saville <w...@saville.com> wrote:
> In rereading "Lifecyle of an Android Application" herehttp://code.google.com/android/intro/lifecycle.html
> it mentions 5 "processes": foreground, visible, service, background & empty.
> In this context I would assume a "process" was a separate address
> space, but at least a separate thread.

Sorry, these aren't processes, these are different states a particular
process can be in, depending on the state of all of the components
(activities, intent receivers, services, content providers) running in
it.

> Then, in the documentation for Activity the "Process Lifecycle" section ofhttp://code.google.com/android/reference/android/app/Activity.html
> talks about 3 "activities" and 1 process: foreground, visible,
> background & empty,
> (Note: Service is missing, is the a documentation error or is "Process
> Lifecycle"
> different from an Application Lifecycle?)

The activity documentation (and service, intent receiver) is intended
to only talk about the details of how that component impacts its
process's overall state. The process lifecycle doc is an overview of
how all of those components come together to result in the final state
of a process.

> Anyway, here it says "The system will kill less important processes..."
> which
> implies to me that they are each a "activity/process" is a linux
> process (i.e. a different address space).

No, one process can run any number of components (activities, intent
receivers, services, content providers) and its state will be the
highest state of all those components. By default all of the
components in your .apk run in a single process, that is created for
that .apk, and the system always calls into them from the main thread
of that process.

Wink Saville

unread,
Jan 10, 2008, 7:58:31 PM1/10/08
to android-d...@googlegroups.com
hackbod wrote:
> On Jan 8, 6:35 pm, Wink Saville <w...@saville.com> wrote:
>
> <snip>
Thanks for that clarification, I suspect I'm not the only
person in the world with some incorrect notions. I'd like
to suggest that there needs to be some more prominent
documentation clarifying these issues.

I'm still fuzzy on how the system can "kill less important processes"
but its probably not important just yet, but someday I
suspect it will be:)

Cheers,

Wink Saville

Reply all
Reply to author
Forward
0 new messages