user971741
user971741

Reputation:

Thread not moving to notify after wait is being called

I have this below piece of code, I want to my thread to wait untill either of the callback functions are called.

Issue my code hits the line where i am making the synchObj wait but after that it just vanishes it doesn't move anywhere.

If after wait its not gonna move ahead how the notify will be called?

iGPlaceApi.getStreams(new Callback<mGooglePlacesApiResponse>() {

    @Override
    public void failure(RetrofitError retrofitError) {
        String serverResponse = retrofitError.toString();
        synchronized (synchObj) {
            synchObj.notify();
            //synchObj.notifyAll();
        }
    }

    @Override
    public void success(mGooglePlacesApiResponse googlePlacesObj, Response arg1){
        nearbyPlaces = new String[googlePlacesObj.results.size()][4];
        for (int i = 0; i < googlePlacesObj.results.size(); i++) {
            mGooglePlaces.place place = googlePlacesObj.results.get(i);
            nearbyPlaces[i][0] = place.icon;
            nearbyPlaces[i][1] = place.name;
            nearbyPlaces[i][2] = String.valueOf(place.geometry.location.lat);
            nearbyPlaces[i][3] = String.valueOf(place.geometry.location.lng);
        }
        synchronized (synchObj) {
            synchObj.notify();
            //synchObj.notifyAll();
        }
    }

});

synchronized (synchObj) {
    synchObj.wait();
}

Handler handler=new Handler();
            Runnable thr = new Runnable() {
                public void run() {
                    iGPlaceApi.getStreams(new Callback<mGooglePlacesApiResponse>() {

                        @Override
                        public void failure(RetrofitError retrofitError) {
                            String serverResponse = retrofitError.toString();
                            synchronized (synchObj) {
                                synchObj.notifyAll();
                            }
                        }

                        @Override
                        public void success(mGooglePlacesApiResponse googlePlacesObj, Response arg1) {
                            nearbyPlaces = new String[googlePlacesObj.results.size()][4];
                            for (int i = 0; i < googlePlacesObj.results.size(); i++) {
                                mGooglePlaces.place place = googlePlacesObj.results.get(i);
                                nearbyPlaces[i][0] = place.icon;
                                nearbyPlaces[i][1] = place.name;
                                nearbyPlaces[i][2] = String.valueOf(place.geometry.location.lat);
                                nearbyPlaces[i][3] = String.valueOf(place.geometry.location.lng);
                            }
                            synchronized (synchObj) {
                                synchObj.notifyAll();
                            }

                        }

                    });
                }
            };
            handler.post(thr);

            synchronized (synchObj) {
                synchObj.wait();
            }

Upvotes: 0

Views: 73

Answers (2)

s0nicYouth
s0nicYouth

Reputation: 500

You are doing it wrong. Handler task will be executed on the same thread so in your case it will never be executed. If you want to wait for your task to be done you should use Thread like this:

// defined somewhere
boolean done = false;
Thread thr=new Thread(Runnable() {
    public void run() {
        iGPlaceApi.getStreams(new Callback<mGooglePlacesApiResponse>() {
            @Override
            public void failure(RetrofitError retrofitError) {
                String serverResponse = retrofitError.toString();
                        synchronized (synchObj) {
                            done = true;
                            synchObj.notifyAll();
                        }
                    }

                    @Override
                    public void success(mGooglePlacesApiResponse googlePlacesObj, Response arg1) {
                        nearbyPlaces = new String[googlePlacesObj.results.size()][4];
                        for (int i = 0; i < googlePlacesObj.results.size(); i++) {
                            mGooglePlaces.place place = googlePlacesObj.results.get(i);
                            nearbyPlaces[i][0] = place.icon;
                            nearbyPlaces[i][1] = place.name;
                            nearbyPlaces[i][2] = String.valueOf(place.geometry.location.lat);
                            nearbyPlaces[i][3] = String.valueOf(place.geometry.location.lng);
                        }
                        synchronized (synchObj) {
                            done = true;
                            synchObj.notifyAll();
                        }

                    }

                });
            }
        });
        thr.start();

        synchronized (synchObj) {
            while (!done) {
                synchObj.wait();
            }
        }

Note that instead of just runnable I'm using Thread, and done variable which indicates task status which is neccesary since wait call can spontaneously wake up and you have to call it again if the task has not been finished yet.

Upvotes: 0

njzk2
njzk2

Reputation: 39386

You can't do that. The callbacks are going to be called on the same thread that is calling the getStreams method.

The callbacks cannot be called until your calling method returns. You probably need to call getStreams in yet another thread.

Upvotes: 0

Related Questions