13

I know similar questions have been asked multiple times. I think i read most of it. But none answer is applicable.

I need to pass complex Objects via Intents (Activity calls/Broadcasts). Everything is done within my process. That's why I see no reason to write my objects into Streams just to reassemble them a few milliseconds after. I want to pass my object reference through my application. Is there any way to do this.

Since my application will broadcast the same Event multiple times in a row I can't rely on static members. I need to get exacly the same object for what I broadcasted.

That's why I was thinking about a static "Referenceholder" that will accept an Object and return an integer that identifies this object in it's internal list so I can pass this integer via .putExtras. But as far as I know Java I could not clean up this Object from this list after it has been added because multiple Listeners could be interessted in the very same object and I would have to keep it in my Referenceholder for ever (assuming that a thread may be resumed at any time - even 2 minutes later).

Any ideas? Am I doing something wrong? Or any ideas of how I can clean up my referneces (probably after some seconds? this may lead to a crash but it seems to be more applicable than writing code that assembles and reassembles my objects for no reason)

Chris
  • 661
  • 2
  • 7
  • 23

2 Answers2

8

Your options are pretty clear: There is no way to pass an un-marshallable object (Parcelable, Serializable) in an Intent. Full stop.

What you might be able to do is to pass something that is a reference to an un-marshallable object. The idea is that you would do something on the order of passing a key to a map that maps that key to the value that you are interested in passing. If both the Intent sender and the intent recipient have access to the map, you can communicate a reference to the un-marshallable object.

I don't understand, exactly, why you think static members are not what you want. I would guess that a static map, in a custom Application object, would be pretty much exactly what you want. ... and I suspect, from your comment about WeakHashMaps, that you've discovered exactly that.

... except that nothing you've said so far explains why you want to make your map Weak. Before you use a Weak map, have a look at Soft references, to make sure that that is not what you mean.

Best of luck

G. Blake Meike
  • 6,615
  • 3
  • 24
  • 40
  • Some people recommanded in similar questions to use a static field in the Application object to pass the desired object itself. That's what I don't want. A static WeakHashMap is totaly legit. If every reference has been cleared I will never need the object, so WeakRerence is exactly what I need. – Chris Feb 17 '13 at 02:16
  • 1
    @Chris Sorry, I don't understand why you can't use a static variable to **pass an object reference** from one activity to another. There is no danger of memory leak here if ActivityA does `Globals.object = objectIWantToPass;` and then `ActivityB.onCreate()` does `Object myObject = Globals.object; Globals.object = null;` – David Wasser Feb 17 '13 at 11:55
  • 3
    Because its a horrible solution. Its the same reason why you pass objects by reference and not by a static member of class. I consider an activity as a function that does something with the data I pass into it and that will return at some point and in some cases will give some data back to the caller. But it seems that it is the only way... – Chris Feb 17 '13 at 14:16
  • 1
    @Chris: Be aware that if you use a weak map and the only "reference" to the object is the map key that you pass in the intent, the GC may collect the object while you are passing it. ...and I don't understand why you consider a static in the app "horrible". – G. Blake Meike Feb 17 '13 at 16:05
  • 3
    @G.BlakeMeike horrible because global state is considered bad design? – Jose_GD May 31 '13 at 19:24
  • @Jose_GD: Sigh. You mean, like, everything stored in a database? – G. Blake Meike May 31 '13 at 22:10
  • @G.BlakeMeike of course not, I mean this: http://programmers.stackexchange.com/questions/148108/why-is-global-state-so-evil – Jose_GD Jun 03 '13 at 12:32
  • @Chris static field is good enough for this question, and there's no need for any weak or soft references, cuz you need pass the reference exactly, and once you get it, you could remove it. It's just a data transfer realisation, like a data pivot, but nothing to do with software design. – Xavier.S Apr 25 '16 at 08:12
4

EDIT:

Forget about this solution. It does not work. Android is coping the Intent that you pass in .startActivity(). There is no way to get any reference inside a activity. This is - in my opinion - great bu****t my by google. You have to call your activity and place the referneces of your object in static members...

As metioned by G. Blake Meike, there is no way to pass Object references in Android via Intents. But you maybe can use WeakReferences.

A very excelent aticle about this topic is found here: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

I got to that solution through this question: Is it possible to get the object reference count?

So what I'm basically going to do is: I will use Intents as a Key for a WeakHashMap and pass my Object as value. This seems to be the only Object that is suitable as Key since everything you put into the Intents extras will be serialized. Due to that, you can only pass one Object per Intent. You could implement Subclasses inside your Acitivity that can hold your Objects an put this Subclass into the map instead. But I'm still not sure if the Intent object that a receiver will get is the same that the caller created but I think so. If it is not, I will edit this solution (or maybe someone could clear that up).

Community
  • 1
  • 1
Chris
  • 661
  • 2
  • 7
  • 23
  • 2
    I'm not an Android expert, but I doubt that a `WeakReference` will work. The `Serializable` / `Parcelable` requirement *implies* that there is a fundamental underlying requirement the object is deep copied from one place to another. That implies that any form of reference passing won't work; e.g. because we are talking about different memory address spaces. And even if it does work, the rationale must be that sharing reference between instances of an app is bad for other reasons. – Stephen C Feb 17 '13 at 03:24
  • You are right. I tested it. The Intent that a activity receives is not the same as I created. – Chris Feb 17 '13 at 14:16
  • Can I pass Object references in an Intent sent using LocalBroadcastManager if I have a Parcelable wrapping it? – JohnyTex Jun 10 '16 at 14:44