Reputation: 6667
I'm having trouble getting the GPS's onLocationChanged to run on a different thread. I understand how to manage UI thread when I'm calling a function but with the GPS, I don't actively call the function.
My intent is to have a light flash every time the GPS receives a reading. I have put this function in a Runnable. I passed this function to a class that implements LocationListener. Then in the main class, I started a new thread that calls requestLocationUpdates. I was hoping that onLocationChanged of the LocationListener would run in a different thread, post to the callback and make the necessary UI effects in the UI thread. Unfortunately, the program crashes every time it tries to call requestLocationUpdates. What's the proper way of doing it?
Right now it looks something like this
Main class:
final Runnable changeLight = new Runnable(){
public void run(){
// do stuff
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture);
status = (ImageView) findViewById(R.id.status);
database = new DatabaseManager(this);
new Thread(){
public void run(){
location = (LocationManager) getSystemService(LOCATION_SERVICE);
listener = new GPSManager(database, changeLight, light, status);
location.requestLocationUpdates("gps", 10000L, 0, listener);
}
}.start();
}
LocationListener class:
public void onLocationChanged(Location location) {
if (location.getAccuracy() <= 32.0){
light = lightColors.Green;
status.post(callback);
database.insertData(location);
}
else{
light = lightColors.Yellow;
status.post(callback);
}
}
The exception says Can't create handler inside thread that has not called Looper.prepare()
Upvotes: 2
Views: 5618
Reputation: 11
I was running in to the same problem. The solution turns out to be that the new thread where you want to receive Location updates from the Location Manager has to be a Looper thread. To do so, all you should do is add following lines in the run() function of your thread.
Looper.prepare();
Looper.loop();
Upvotes: 1
Reputation: 642
The thread where you call location.requestLocationUpdates must have a Looper ( see here ). You can use HandlerThread instead of Thread.
Upvotes: 3
Reputation: 40345
Could your problems be arising from improper synchronization of the main thread? Do you get any exceptions before the app crashes? Can you post an sscce.org compliant example?
In general when you're processing asynchronous events on the GUI you should have proper synchronization: http://developer.android.com/resources/articles/painless-threading.html
Upvotes: 0