Question

I have following problem. I have this implementation of my Thread with Looper.

public class GeoLocationThread extends Thread{

public Handler handler;
private General general;


public void run(){
    Looper.prepare();       
    handler = new IncomingHandler(general);
    Looper.loop();          

}

public GeoLocationThread(General general){
    this.general=general;
}



private static class IncomingHandler extends Handler{
    private final WeakReference<General> mService; 

    IncomingHandler(General service) {
        mService = new WeakReference<General>(service);
    }

    @Override
    public void handleMessage(Message msg)
    {
         General service = mService.get();
         if (service != null) {
             Location location=service.getLl().getLocation();
                if(location.getAccuracy()<40){                                                                                      
                    service.setOrigin(new GeoPoint((int) (location.getLatitude() * 1E6),(int) (location.getLongitude() * 1E6)));
                }
         }
    }

}

}

and i would like to do the following:

GeoLocationThread locationThread=new GeoLocationThread(this);
locationThread.start();
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll, locationThread.handler.getLooper());

Where lm is LocationManager. From my log and testing I am able to say that locationThread.handler.getLooper() returns null instead of the Looper.

I don't know why it is null. I have tried to call locationThread.isAlive() which has returned true. I have also tried to get locationThread.handler; which I know is not null. I have also done the lot of googling, but I haven't found more than the documentaion.

Thank you very much in advance for your answers.

Was it helpful?

Solution

Your code is reading null most likely because the operations two are not synchronous with each other. You cannot successfully call getLooper() on a Handler until Looper.prepare() is finished and the Handler is constructed. Because Thread.start() does not block while the other thread executes (of course, why would it? that would defeat the purpose of the new Thread) you have created a race condition between the run() block of the Thread and the code trying to set up the location listener. This will produce different results on different devices based on who can execute first.

Furthermore, registering location updates is already an asynchronous process, so one wonders why the secondary thread is needed? You can simply request updates to your listener without passing in a secondary Looper and the listener will get data posted when new updates are available, the main thread does not stay blocks during this process.

OTHER TIPS

Do you have to call super() in your constructor? Maybe the Looper is not getting set because the parent constructor is not being called?

Ok, try this. Make this:

public class GeoLocationThread extends Thread{

be this:

public class GeoLocationThread extends HandlerThread{

then you can do this.getLooper() when you construct the Handler or when you need the looper.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top