2

I have two classes: Server class (plain java class) and MainActivity class (android activity class). I am trying to access a static variable from the Server class with my MainActivity but every time I tried to use the static variable, it always returns null.

Here is my code for the Server class:

public class Server {

  private static String clientMsg;

  public static String getClientMsg() {
      return clientMsg;
  }

  public static void main(String[] args){

    /*Some Server code here*/

    while(true){
        try {
            clientSocket = serverSocket.accept();

            //READ THE MESSAGE SENT BY CLIENT
            dataInputStream = new DataInputStream(clientSocket.getInputStream());

            //Here is where I assigned the static variable clientMsg
            clientMsg = dataInputStream.readUTF();

            dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            dataOutputStream.writeUTF("Message Received!");

        } catch (IOException e) {
            e.printStackTrace();
        }

   /* Rest of the code here */
  }
 }
}

Here is my code for the MainActivity class:

public class MainActivity extends FragmentActivity implements LocationListener{
  private Button connect;
  /*Some variable declarations here*/

  @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main); 

      connect = (Button) findViewById(R.id.connect);

      /*Some code here*/

      connect.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String msg = Server.getClientMsg();
                if(msg != null)
                    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(MainActivity.this, "Client Message is null!", Toast.LENGTH_LONG).show();
            }
        });
    /*Rest of the code here*/
  }
}

No matter how I access the static variable clientMsg from the Server class, it always returns null.

Did I do something wrong in the code? How should I access the static variable? Or it doesn't even have to be static, how do I simply access the variable clientMsg without it returning a null value?

/EDIT/

Sorry for not being clear with my question. I am actually running the 2 classes separately, one as a plain Java that displays in console and the other displays in the Android emulator and lastly, I have a client app running in my android phone.

So basically, I use the client app to send a message to the server which stores the value of the message in the clientMsg variable. Then I tried displaying the value of clientMsg using System.out.println() and it works! But when I access the variable in the MainActivity, its value becomes null. Any reason as to why that is?

7
  • Is your Server code actually running in the same process? Are you sure it's received a message? Commented Jun 7, 2013 at 6:45
  • How are you actually triggering Server's main()? Commented Jun 7, 2013 at 6:45
  • how clientMsg is being set? I see it getting set only from main method Commented Jun 7, 2013 at 6:45
  • @JonSkeet the Server code is running in a separate process and yes, it has received the message sent by the client. Commented Jun 7, 2013 at 7:33
  • @stan07: If it's running as a separate process, it will have a separate static variable. Commented Jun 7, 2013 at 8:03

7 Answers 7

4

No matter how you access the clientMsg it haven't had any value set.

So you will always get null.

If by any chance you expect the main method to run automatically it won't happen. You can call it manually. Or use an static block to do the initialization.

EDIT :

It seems that you are running them in two separate JVMs. Static classes are one per JVM. So when you run them separately one's changes won't be visible to the other...

Sign up to request clarification or add additional context in comments.

6 Comments

He is setting a value, in his Server.main method. I wonder if it's called, though.
@zmbq My understanding was that it was for a test or something... Because I'm pretty sure that's not his app entry point..
With Android you can never tell... Or he's calling it explicitly someplace. But I guess you're right.
Actually, I'm running the 2 classes separately. So I let the client send a message to the server then store it in the clientMsg variable which actually displays the value when I use System.out.println(). But when I accessed it in MainActivity, its value is null. Any ideas as to why that is?
What do you mean by 'running them separately'? You need to update your question to provide some context around what you are doing exactly.
|
1

The static main() method in a class is only called automatically when you 'execute' a class -

  1. from the console using the command as java package.name.Server
  2. from an IDE like Eclipse by running it as 'a Java application'
  3. from a build tool that starts a process which essentially does what is written in Point 1 above.

If you are using Server in an Android application, none of these is true. So if you want the method to be executed, you need to call it yourself, say by invoking it in the beginning of your Activity.

However, the signature public static void main() is conventionally only intended to be called by default while running a class as a Java application, so as Homam has mentioned, you should move the code to the get method to do a lazy initialization. Alternatively, at least rename the main method to something like init() and handle the initialization of the class/variable yourself in some other way.

EDIT (based on feedback provided by OP):

What you need to keep in mind is that these rules only apply when both classes are running in side the same virtual machine. If the Server class is being executed in Eclipse, it runs inside the JVM that Eclipse uses/forks. What happens inside the Android Emulator happens in the Dalvik VM that comes with Android. As far as both environments are concerned, it's no different from running them on two completely different machines. They are two different ClassLoaders, two different memory spaces, and in this case, two different Virtual Machine technologies.

8 Comments

yes! I'm executing the main() method from Eclipse running as Java application while the MainActivity is executing in an android emulator.
Then you have two different Virtual Machines. One is the JVM that is invoked by Eclipse, and the other is the Dalvik VM running inside the Android emulator. There is no shared classloader, memory or anything else, between them. Which is why what you are doing will never work.
so it wont work even when I added the Server project to my MainActivity's Java Build Path?
It won't work unless you ensure that Server.main() is called before the MainActivity tries calling getClientMsg(). Within the same VM.
I did. I even printed it out in the console before I actually clicked the "Connect" button which invokes the getClientMsg() from the Server class.
|
0

The main function where your static variable is given some value is never called. Android wont call the main function for you unlike normal java app. So it will always be null.

1 Comment

I'm actually running the two classes separately and it actually displayed the value when I used System.out.println() inside the Server class. But when I accessed it in the MainActivity class, it returns null.
0

Is your Server.main method ever called?

Anyway, Android sometimes kills your process and starts it up for you, trying to restore it to the last state. If you don't listen carefully to the events, you may end up missing this. Between those restarts, static variables are reset to their default values.

Unfortunately, I couldn't find a decent document describing application life-cycles, just one describing activity life-cycles. I don't want to be rude, so let's just say Android usually moves things from one place to the other using suction.

1 Comment

I'm actually running the 2 classes separately. I edited the question to make it clearer.
0

Put the code of main function to getClientMsg function and remove main function, you don't need it here.

Comments

0

Try like this:

public class Server {

    private static String clientMsg;

    public static String getClientMsg() {
        while (true) {
            try {
                clientSocket = serverSocket.accept();

                // READ THE MESSAGE SENT BY CLIENT
                dataInputStream = new DataInputStream(
                        clientSocket.getInputStream());

                // Here is where I assigned the static variable clientMsg
                clientMsg = dataInputStream.readUTF();

                dataOutputStream = new DataOutputStream(
                        clientSocket.getOutputStream());
                dataOutputStream.writeUTF("Message Received!");

            } catch (IOException e) {
                e.printStackTrace();
            }

            /* Rest of the code here */
        }

        return clientMsg;
    }

}

1 Comment

Thanks for the tip! But I'm actually running the two classes separately so I might still have to use the main() in the Server class.
0

Here is the problem:

Initially value of clientMsg will be null. Now you are assigning value to clientMsg through code which is written inside main function and main function will never be called.

So the value of clientMsg remains null.

Solution: put whole code inside getClientMsg() method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.