Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help with callbacks and anonymous classes in Java

I am using some third party library to connect to a server via async protocol and get response back. For example method to get userid by username looks like this:

public int getUserid(String username) {
        int userid = 0;

    connection.call("getUserid", new Responder() {
        public void onResult(final int result) {
            System.out.println("userid: " + result);
            //how to assign received value to userid and return it?
        }
    }, username);

    //wait for response
    while (userid == 0) {
            try{
                Thread.sleep(100);
            } catch (Exception e) {}
        }


        return userid;
}

The problem is I can't assign returned "result" from server response to "userid" variable from the method (in order to return it after). How to solve this? I probably can assign it to some class variable rather than method variable but I want to keep it within method scope so I don't have to deal with concurrency issues.

Thanks.

like image 626
serg Avatar asked May 28 '09 01:05

serg


1 Answers

If I understand your question correctly, you're asking how you can write a variable from inside an anonymous class.

Anonymous classes can only access final variables, and can't directly "write" them.

A straightforward solution that is "good enough" is to create sort of a ValueBox class with a single value field and a getter and setter. You can then instantiate a new one in the function as a final variable, and have your anonymous class access it. The anonymous class will use its getter and setter to write/read.

The fact that the variable is final just means that you can't aim the reference anywhere else, but you can still change the contents of the referred object from either function.

The bigger problem you are going to have is in waiting until the callback has been called. This sort of wait-sleep might be good enough, but you may want to consider timeouts, threads, etc, depending on what you're trying to achieve.

In addition, this all assumes that you are never going to call this twice on the connection. Otherwise, you need to provide more info to us on your synchronization model.

Here's some sample code:

public int getUserid(String username) {
        final ValueBox<Integer> userid = new ValueBox<Integer>();

        connection.call("getUserid", new Responder() {
                public void onResult(final int result) {
                        System.out.println("userid: " + result);
                        userId.setValue(result);
                        //how to assign received value to userid and return it?
                }
        }, username);

        //wait for response
        while (userid.isEmpty()) {
                try{
                        Thread.sleep(100);
                } catch (Exception e) {}
        }

      return userid.getValue();
}
like image 115
Uri Avatar answered Oct 18 '22 07:10

Uri