Android MapActivity thread question
How do I ensure code is or is not executed on the UI thread in an Android MapActivity project?
I am developing an Android map-based application, but I have experienced some stability issues and my research has led me to believe I need to ensure that screen updates are carried out on the UI thread.
My app has data coming in from a GPS listener (which I wo开发者_如何学Gould like to configure as a separate thread) and a UDP listener (which is already a separate thread), and it has the usual set of android software life cycle methods, but I must be inexperienced or something, because I have no idea where to put code that updates the map overlays
(a) on the UI thread, (b) in a recurring manner.
I have no preference between a polling or an event-driven process (timer-based perhaps, or the arrival of incoming data), so suggestions of either type will be gratefully accepted.
Anyone got any ideas??
Thanks, R.
Read this post on painless threading, particularly the Activity.runOnUIThread
You can also look at this Handling Expensive Operations in UI Thread. In your case you can do the following:
public class MyActivity extends Activity {
[ . . . ]
// Need handler for callbacks to the UI thread
final Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setup location listener
[ . . . ]
startNonUIThread();
}
protected void startNonUIThread() {
// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
try{
while(true){
sleep(1000);
mHandler.post(mUpdateResults);
}
}catch(InterruptedException e){
//blah blah
}
}
};
t.start();
}
private void updateResultsInUi() {
// Back in the UI thread -- update UI elements based on data from locationlistener
//get listener location
//use the location to update the map
[ . . . ]
}
}
The android location service is a module that runs in the background so you do not need to seperate it in another thread.
However I would not recommend you to use java thread class or runnable interface at all, use async task instead which performs all the thread management for you. Have a look at the android developers blog, Painless Threading.
To update your UI thread on location updates you can use update handlers. Everytime there is GPS data avialable a message is transmitted to the update handler in you main ui thread.
E.g.
public void onLocationChanged(Location location) {
location = this.lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
try {
this.mLongitude = location.getLongitude();
this.mLatitude = location.getLatitude();
Message msg = Message.obtain();
msg.what = UPDATE_LOCATION;
this.SystemService.myViewUpdateHandler.sendMessage(msg);
} catch (NullPointerException e) {
Log.i("Null pointer exception " + mLongitude + "," + mLatitude, null);
}
}
And in your main activity class:
Handler myViewUpdateHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_LOCATION:
//do something
}
super.handleMessage(msg);
}
};
精彩评论