4

Is something wrong with this construct in Android?

class A extends Activity {

private Object myObject = new Object();

@Override
protected void onCreate(Bundle savedInstanceState) {
    //myObject = new Object();
}

}

Because at some point(s) later I get (sometimes, not reproducible yet) exceptions because myObject is null. I don't know if it's because I have to initialize in onCreate.

Edit: Additional details:

  • The actual class of myObject is List<Object> (Where Object is a domain specific type)

  • At some point later in the activity I'm storing myObject as a static field of a "Parameter passer" class and starting other Activity (because I'm avoiding to implement Parcelable. If this is good or bad practice should not be discussed here, unless that's causing my error). In the other Activity I pick up myObject. There it's (sometimes) null.

Edit 2: I don't understand why this object becomes null if I'm storing a reference to it as static field of my parameter passer class (a standalone, dedicated class). That's how garbage collection works, right, it just removes when the objects are not referenced anymore. So since I have a static reference this object should not be removed. According to this thoughts, if they are correct, the problem should be somewhere else.

User
  • 31,811
  • 40
  • 131
  • 232

3 Answers3

2

When you start a new activity your old one goes on the block for possible garbage collection (including any classes instantiated in it, including your parameter passer class), so your object is not necessarily going to be available (which is why you see an intermittent failure.).

I see two option:

1) Pass it along in the bundle with your intent that starts the new activity. As you were trying to avoid this, probably not your best choice.

2) Extend the Application class and store the object in there.

EDIT

I think the accepted answer to this SO Question might fix your issue (and explain what is actually happening).

Community
  • 1
  • 1
Barak
  • 16,318
  • 9
  • 52
  • 84
  • I added a second edit to my post related to your answer. Could you please give me an answer to that. – User Jun 22 '12 at 14:20
  • Btw. my parameter passer class is a standalone class with static field. That could not be in the block for possible garbage collection (if yes, why?). – User Jun 22 '12 at 14:21
  • Uhm... it looks like the cleanest solution is to parcel all my parameters... at least to exclude that this is causing the errors... – User Jun 22 '12 at 14:59
  • Your static variables in your parameter passer class will not be garbage-collected. – David Wasser Jun 22 '12 at 15:50
  • They will if the ClassLoader that loaded the class gets garbage collected. Hence the recommendation in the link I posted to keep a reference to the parameter passer class in the activity. – Barak Jun 22 '12 at 16:00
  • I don't understand how the ClassLoader that loaded the parameter passer could be different from the ClassLoader that loaded the rest of his application. In theory, yes. But in practice? I don't think so. – David Wasser Jun 22 '12 at 16:49
  • I also don't understand that, but I'll do everything with Parcelable and remove the static stuff. It seems to be the best solution, at least according to Android environment. And it also works restoring saved state, after Activity has been killed, like David Wasser noted. If after that I still get errors, well, then I have to fix something else. – User Jun 22 '12 at 21:59
1

No. That code is just fine. You can create objects in the constructor.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • So far, based on what you've written, it all looks OK to me. You must be missing something else that you haven't told us. – David Wasser Jun 22 '12 at 14:25
  • Add some debug logging to ensure that the object reference is actually non-null when you put it into your parameter-passing class. – David Wasser Jun 22 '12 at 14:26
  • yes, thanks, I did that already. It's impossible that my parameter is null before I'm passing it. – User Jun 22 '12 at 15:15
  • The only other possibility is that the OS is killing your process (if it is idle for some period of time). Then, when the user returns to the task, the OS will recreate your process and restart the topmost activity on the task stack. In this case, your static variables will be null. – David Wasser Jun 22 '12 at 15:49
  • I don't think that that is causing the errors I currently have, but it's very important to handle this. I'll just do everything with Parcelable and remove my static vars, it seems to be the best solution. If errors keep appearing then I know the problem is something else... +1 for helpful answer. – User Jun 22 '12 at 21:56
0

You may want to check a previous question about it Instance variable initialization in java and the section 3.2.4. Field Defaults and Initializers which basically states that the first case:

private Object myObject = new Object();

is identical to an initialization in the class constructor. (NOTICE onCreate is NOT the constructor).

So, myObject should never be null, except in the case the "new Object()" instruction failed, generating an exception.

Isn't this possible your code is changing the contents of myObject later on the code?

Community
  • 1
  • 1
Carlos Barcellos
  • 544
  • 1
  • 4
  • 10
  • Yes but this is not a constructor, it's the onCreate() method which is called by the Android framework... And the class is an Activity, and there is maybe some misterious management by Android... But it's very problably something else is wrong, I just wanted to make sure this is not the reason of my error. – User Jun 22 '12 at 14:32
  • Now I better understood your problem. Actually this is indeed related with the Garbage Collector (seems to be a bug in the core, as you have a static field still pointing to it). One way I can think of avoiding the Parcelable is to create a service, call the other activity from this service and only close the service after receiving a message from the latter activity -- it may work. – Carlos Barcellos Jun 22 '12 at 16:56
  • I'm not sure if the static things are the actual reason of my problem. Why do you say "seems to be a bug in the core" do you have certain knowledge about this? – User Jun 22 '12 at 22:02
  • Actually no, but if you are keeping a reference to it this should not be GC'd. – Carlos Barcellos Jun 23 '12 at 10:54