Properly dealing with network on main thread connection in drawing overlays on map for android tablet
After playing with honeycomb a lot, it turns out if you do any HTTP stuff it wines about a NetworkOnMainThread issue. I was dealing with this by putting my calls to http in a separate AsynTask and this seemed to work well...
Now I am trying to load a WMS layer im fetching (Via https) and put it开发者_运维知识库 on the map. This is working okay but my way of using AsyncTask isn't cutting it as everytime the draw was called on the overlay (which I think is everytime you move the map) it was doing another
new getWmsAsync().execute();
which means after a while there was max threads.
I am not sure what the right fix for this is. Or how to engineer this in the correct way after doing it the way I knew how failed me. What pieces am I missing? Is there away to get the https request on a different thread (it has to be done every time the map is moved I think).
The original calls:
in the WMSOverlay extends Overlay
class:
@Override
public void draw(Canvas canvas, MapView mapView,
boolean shadow) {
super.draw(canvas, mapView, shadow);
mCanvas=canvas;
wmsclient = new WMSLoader(mapView.getContext());
cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);
//new getWmsAsync().execute();
Paint semitransparent = new Paint();
semitransparent.setAlpha(0x888);
mCanvas.drawBitmap( , 0, 0, semitransparent);
}
But my wsmClient.loadMap
has http calls in it so it dies with the above NetworkOnMainThread. My fix was this:
@Override
public void draw(Canvas canvas, MapView mapView,
boolean shadow) {
super.draw(canvas, mapView, shadow);
mCanvas=canvas;
wmsclient = new WMSLoader(mapView.getContext());
cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);
new getWmsAsync().execute(); //too many threads here...
}
private class getWmsAsync extends AsyncTask<Void, Void, Bitmap>{
@Override
protected void onPostExecute(Bitmap image) {
Paint semitransparent = new Paint();
semitransparent.setAlpha(0x888);
mCanvas.drawBitmap(image, 0, 0, semitransparent);
this.cancel(true);
}
@Override
protected Bitmap doInBackground(Void... params) {
// TODO Auto-generated method stub
return wmsclient.loadMap(mCanvas.getWidth(), mCanvas.getHeight(), cornerCoords[0], cornerCoords[1], null);
}
}
if I use that way with the .execute()
i end up with this error:
08-23 17:01:05.520: ERROR/AndroidRuntime(5436): java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@41147c88 rejected from java.util.concurrent.ThreadPoolExecutor@40880c00[Running, pool size = 128, active threads = 127, queued tasks = 10, completed tasks = 59]
After playing with honeycomb a lot, it turns out if you do any HTTP stuff it wines about a NetworkOnMainThread issue.
AFAIK, you should only get messages if you are using StrictMode
. Regardless, more important than the LogCat messages is that you are freezing your UI if you do network I/O on the main application thread.
I am not sure what the right fix for this is.
Well, typically, you cache your HTTP request results, so you do not need to re-request them.
Or, if each of your requests would be for different data, wait until the user pauses, then do a single request for the end result, the same way Google Maps does it for its own map tiles.
精彩评论