Global objects


Last Updated:

  1. andywhoa

    andywhoa Well-Known Member This Topic's Starter

    Joined:
    May 15, 2010
    Messages:
    105
    Likes Received:
    13
    What is the standard regarding global objects in Java? Say I want an object that contains some pertinent information about the application to be accessed by any Activity. Where/how do I declare this? Or is this a bad idea?

    Example: Suppose my Android app makes web service calls back to my website and with each call I must provide the user's username and password. This information is collected (and validated) with the first Activity (login screen) and kept in memory and passed around to be used with each web service call.

    Thanks for your help,
    Andrew
     

    Advertisement
  2. markb

    markb Well-Known Member

    Joined:
    Sep 14, 2009
    Messages:
    148
    Likes Received:
    26
    Hi andywhoa,

    A number of approaches spring to mind. Some will be more appropriate than others, depending on the situation.

    If you wanted a single global object, accessible throughout your code then you could use something called a singleton. It's a design pattern (reusable bits of design that have been identified as useful, which come up a lot, and have been documented). The singleton pattern describes a common situation where you want one and only one instance of an object.

    Simply Singleton - JavaWorld

    On the other hand, that might be overkill. Some OO design principles can be allowed to slip a bit when there are more important factors. For example, when I write java web apps (my day job) I'll use design patterns, and try to keep the design clean. But at home working on Android, I'll break the rules to get more efficient or faster code.

    So for your Android app, you could just have static members in a class. You could make them public and accessible to all of your code. That's the other extreme. Depending on what the data is, you might want to keep the data private and provide methods to set and get the values. Maybe a value could be updated from multiple threads, in which case you have to deal with that.

    I hope that helps. If it doesn't make much sense let me know and I'll try to explain it better.

    Mark
     
    andywhoa likes this.
  3. andywhoa

    andywhoa Well-Known Member This Topic's Starter

    Joined:
    May 15, 2010
    Messages:
    105
    Likes Received:
    13
    The problem here is (and I've never coded for mobile; so I'm assuming) that first (or any) Activity is not going to be on the stack throughout the entire workflow. So where does the singleton live so that it can be accessed from any Activity?

    Unless I'm confusing myself, I would essentially need to extend Activity, create this public static, and then all of my Activities would extend that so they would all have the public static.

    Forgive me, I'm both new to Android and Java (essentially anyway)

    Thank you for your reply
     
  4. markb

    markb Well-Known Member

    Joined:
    Sep 14, 2009
    Messages:
    148
    Likes Received:
    26
    It's much simpler than I think you think it is.
    You can just create a new class, it doesn't have to have anything to do with an Activity, or any other class.

    Here's how to do it with a new class with public static data members.

    For example, in UserData.java

    Code (Text):
    1.  
    2. public class UserData
    3. {
    4.   public static String userName = "" ;
    5.   public static String userPassword = "" ;
    6. }
    7.  
    In your activity, let's say it's MyActivity.java

    Code (Text):
    1.  
    2. public class MyActivity extends Activity
    3. {
    4.   private void doSomethingWithUserData()
    5.   {
    6.     String name = UserData.userName ;
    7.     String pass = UserData.userPassword ;
    8.  
    9.     // do something with data . . .
    10.  
    11.   }
    12.  
    13.   private void setUserData()
    14.   {
    15.     UserData.userName = "bob" ;
    16.     UserData.userPassword = "secret" ;
    17.   }
    18.  
    19.   ... etc ...
    20. }
    21.  

    If you wanted to do it with a singleton it'll be similar. The singleton class doesn't have to have anything to do with an Activity. It's just a separate class.

    I'll adapt the example in the website I linked to.

    Here's the UserData class done as a singleton:

    Code (Text):
    1.  
    2. public class UserData {
    3.    private static UserData instance = null;
    4.    
    5.    private String userName = null ;
    6.    private String userPassword = null ;
    7.  
    8.    protected UserData() {
    9.       // Exists only to defeat instantiation.
    10.    }
    11.  
    12.    public static UserData getInstance() {
    13.       if(instance == null) {
    14.          instance = new UserData();
    15.       }
    16.       return instance;
    17.    }
    18.  
    19.    public void setUserName(String name)   { userName = name ; }
    20.    public void setUserPassword(String pass)   { userPassword = pass ; }
    21.  
    22.    public String getUserName() { return userName ; }
    23.    public String getUserPassword() { return userPassword ; }
    24.  
    25. }
    26.  

    The activity would be changed to use the singleton as follows:

    Code (Text):
    1.  
    2. public class MyActivity extends Activity
    3. {
    4.   private void doSomethingWithUserData()
    5.   {
    6.     String name = UserData.getInstance().getUserName() ;
    7.     String pass = UserData.getInstance().getUserPassword() ;
    8.  
    9.     // do something with data . . .
    10.  
    11.   }
    12.  
    13.   private void setUserData()
    14.   {
    15.     UserData instance = UserData.getInstance() ;
    16.  
    17.     instance.setUserName("bob") ;
    18.     instance.setUserPassword("secret") ;
    19.   }
    20.  
    21.   ... etc ...
    22. }
    23.  
    Note that the singleton object gets created the first time anything tries to access it.
    The first call to getInstance() will create the object if it doesn't already exist. There will only ever be one instance, and it can only be got at through the static method UserData.getInstance()

    Mark
     
    andywhoa likes this.
  5. andywhoa

    andywhoa Well-Known Member This Topic's Starter

    Joined:
    May 15, 2010
    Messages:
    105
    Likes Received:
    13
    Ahhhh

    Thank you very much. This is extremely helpful :D
     
  6. andywhoa

    andywhoa Well-Known Member This Topic's Starter

    Joined:
    May 15, 2010
    Messages:
    105
    Likes Received:
    13
    Quick followup question:

    So far, in playing around with the SDK, I've limited myself to 1 package, which contains my Activities. Per Java conventions, would my singleton be a part of a different package? What would be a good naming scheme for this package?
     
  7. markb

    markb Well-Known Member

    Joined:
    Sep 14, 2009
    Messages:
    148
    Likes Received:
    26
    The answer has to be "it depends". :)

    But I wouldn't get too hung up about conventions.
    If all your classes naturally fall into one package then I wouldn't create a new package for the singleton. Keep it simple. If it turns out to less than optimal then you can always change it.

    If your application naturally splits into a number of packages, such as:

    Code (Text):
    1.  
    2.   myapp.db      -- all the DB access code
    3.   myapp.gui     -- all the GUI code
    4.   myapp.model   -- classes that model the data in your app
    5.   myapp.ws      -- code to handle web services
    6.   myapp.utils   -- generic utility code
    7.  
    Then the singleton could go into the most suitable package. So if the singleton wasn't really going to be used by the whole app, but just by the web services code, then the singleton should go into that package.

    Just because the singleton class is in one package doesn't stop it from being accessed by other packages. (Although you can arrange such a restriction if you wanted to.)

    Unless you're planning to release your source code to the public, it really doesn't matter too much. If everything goes in one package that's fine. If you start to get lost in the code because there's so much of it, then you might want to start breaking it up into separate packages. You might not know what the correct split is until you've written all the code.

    Eclipse has a nice "refactoring" tool which lets you move things around. I've refactored bits of code into many different package schemes several times over an hour. Sometimes you just have to try it out, live with it for a bit, to see if it feels right. At least Eclipse makes it easy. :)

    Let me know if you need more info (if I haven't gone on for too long already).

    Mark
     
    andywhoa likes this.
  8. andywhoa

    andywhoa Well-Known Member This Topic's Starter

    Joined:
    May 15, 2010
    Messages:
    105
    Likes Received:
    13
    No, that was a quite useful explanation. Thank you.

    I'm being slightly anal about this because I'm building this application from the ground up for my new employer. Since it's been quite a long time since I've used Java (and having never used Android), I don't want to break conventions too early. We're all (I've worked with all of these people previously) C programmers; so we'll eventually bend Java conventions where we see fit, but for a solid foundation I'd like to start the project properly. Your example packages are likely what the architecture will look like. Per your example, I suspect the gui, model, ws and utility packages will all need access to some global information.



    Your mention of a utils project springs a few questions, but I've already created another thread for that.



    Thank you for all your help and time
     
  9. jonbonazza

    jonbonazza Well-Known Member

    Joined:
    Jul 13, 2010
    Messages:
    1,934
    Likes Received:
    458
    A more proper implementation would be:

    Code (Text):
    1. public class UserData
    2. {
    3.   private String userName = "" ;
    4.   private String userPassword = "" ;
    5.  
    6.   public String getUserName()
    7.   {
    8.       return userName;
    9.   }
    10.   public String getPass()
    11.   {
    12.       return userPassword;
    13.   }
    14.   public void setUserName(String user)
    15.   {
    16.       userName = user;
    17.   }
    18.   public void setPassword(String pass)
    19.   {
    20.       userPassword = pass;
    21.   }
    22. }
    and in MyActivity.java

    Code (Text):
    1. public class MyActivity extends Activity
    2. {
    3.   private void doSomethingWithUserData()
    4.   {
    5.     String name = UserData.getUserName();
    6.     String pass = UserData.getPass();
    7.  
    8.     // do something with data . . .
    9.  
    10.   }
    11. }
    You should keep your member variables as private as possible.
     
  10. markb

    markb Well-Known Member

    Joined:
    Sep 14, 2009
    Messages:
    148
    Likes Received:
    26
    But not if you've already considered the trade off between design and efficiency, and were deliberately discussing and illustrating the 2 extremes.

    And if you go back and read my 1st post in this thread you'll see that's exactly what I was doing.
     
  11. jonbonazza

    jonbonazza Well-Known Member

    Joined:
    Jul 13, 2010
    Messages:
    1,934
    Likes Received:
    458
    Ah I did miss that part. I apologize.
     
  12. markb

    markb Well-Known Member

    Joined:
    Sep 14, 2009
    Messages:
    148
    Likes Received:
    26
    No problem at all. :)

    And for the record, I would never do it that way in my day job. (People would point and laugh at me.)

    But I have written code like that in a game I'm writing for Android, where I'm trying to keep it fast. And in other parts of the code I try to make sure I don't allocate any new objects once the game has started. So it's not code I'd claim to be proud of.

    For more on the topic of optimising for games, there's a Google I/O presentation here:
    (which makes me feel less guilty about my code):

    Google I/O - Writing Real-Time Games for Android

    Mark
     

Share This Page

Loading...