I have a MyMapActivity with private class extending AsyncTask for purpose to do request on server every time when map section is changed (onMove() method). Response from server is JSON data string which could be about 1-3 MB. So I need to avoid multiple calls to server when user is moving the map to avoid OutOfMemory. For that reason I'm trying to check if my own AsyncTask is cancelled (on every onMove() start) and if not(I suppose that indicates about performing doInBackground() method) I'm tying to cancel it. But regardless of this I still have a
01-19 20:45:05.660: ERROR/MapActivity(2482): Couldn't get connection factory client 01-19 20:45:40.600: ERROR/Tethering(96): active iface (usb0) reported as added, ignoring 01-19 20:47:15.260: ERROR/dalvikvm-heap(2482): Out of memory on a 11908-byte allocation. 01-19 20:47:15.270: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=23091KB, Bitmap Size=101KB 01-19 20:47:15.410: ERROR/dalvikvm-heap(2482): Out of memory on a 7690-byte allocation. 01-19 20:47:15.420: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=23088KB, Bitmap Size=101KB 01-19 20:47:15.570: ERROR/dalvikvm-heap(2482): Out of memory on a 7656-byte allocation. 01-19 20:47:15.590: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=23090KB, Bitmap Size=101KB 01-19 20:47:15.730: ERROR/dalvikvm-heap(2482): Out of memory on a 9098-byte allocation. 01-19 20:47:15.740: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=23097KB, Bitmap Size=101KB 01-19 20:48:01.850: ERROR/dalvikvm-heap(2482): Out of memory on a 8176-byte allocation. 01-19 20:48:01.850: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=22767KB, Bitmap Size=101KB 01-19 20:48:01.970: ERROR/dalvikvm-heap(2482): Out of memory on a 12022-byte allocation. 01-19 20:48:01.980: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=22768KB, Bitmap Size=101KB 01-19 20:48:02.110: ERROR/dalvikvm-heap(2482): Out of memory on a 8936-byte allocation. 01-19 20:48:02.119: ERROR/dalvikvm(2482): Out of memory: Heap Size=24519KB, Allocated=22769KB, Bitmap Size=101KB 01-19 20:48:07.220: WARN/dalvikvm(2482): threadid=20: thread exiting with uncaught exception (group=0x400259f8) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): FATAL EXCEPTION: AsyncTask #9 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): java.lang.RuntimeException: An error occured while executing doInBackground() 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at android.os.AsyncTask$3.done(AsyncTask.java:200) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.lang.Thread.run(Thread.java:1102) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): Caused by: java.lang.OutOfMemoryError 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.lang.String.(String.java:468) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.lang.StringBuilder.toString(StringBuilder.java:664) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.stream.JsonReader.nextString(JsonReader.java:995) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.stream.JsonReader.nextValue(JsonReader.java:810) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.stream.JsonReader.objectValue(JsonReader.java:790) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.stream.JsonReader.quickPeek(JsonReader.java:385) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.stream.JsonReader.peek(JsonReader.java:348) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:322) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:334) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:170) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:38) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:71) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:170) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.Gson.fromJson(Gson.java:720) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at com.google.gson.Gson.fromJson(Gson.java:660) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at net.amagumo.realestate.MyMapActivity$MyTask.getHttpContent(MyMapActivity.java:444) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:393) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:1) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at android.os.AsyncTask$2.call(AsyncTask.java:185) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 01-19 20:48:07.350: ERROR/AndroidRuntime(2482): ... 4 more 01-19 20:48:07.450: WARN/ActivityManager(96): Force finishing activity net.amagumo.realestate/.MyMapActivity 01-19 20:48:21.290: WARN/TimeThread(294): conver time failed 01-19 20:48:42.899: WARN/TimeThread(294): conver time failed
Here is my activity class:
public class MyMapActivity extends MapActivity implements LocationListener, OnTouchListener, OnMoveListener, MyMapItemClickedListener, DefaultActivity { MyMapView mv; MapController mc; LocationManager lm; MyItemizedOverlay myOverlay; DatabaseAdapter db; AdvertResult advertResult; String callerActivityString; MyTask mytask; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(Constants.DEBUG_TAG, "MAP - create"); setContentView(R.layout.map); db = new DatabaseAdapter(getApplicationContext()).open(); mv = (MyMapView)this.findViewById(R.id.mapView); mc = mv.getController(); lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); mv.setOnTouchListener(this); mv.setmOnMoveListener(this); mv.setSatellite(true); Drawable marker=getResources().getDrawable(R.drawable.ic_maps_indicator_startpoint_list); int markerWidth = marker.getIntrinsicWidth(); int markerHeight = marker.getIntrinsicHeight(); marker.setBounds(0, markerHeight, markerWidth, 0); myOverlay = new MyItemizedOverlay(marker); myOverlay.setMyMapItemClickedListener(this); mv.getOverlays().add(myOverlay); advertResult = new AdvertResult(); mytask = new MyTask(); } public void completeMap(){ Log.d(Constants.DEBUG_TAG_MAPS, "completing map - START"); for(AdvertSimple is : advertResult.getAdvertSimpleList()){ if(is.getAdress().getLat()!=null && is.getAdress().getLon()!=null){ GeoPoint gp = new GeoPoint(is.getAdress().getLat(), is.getAdress().getLon()); myOverlay.addItem(gp, "Advert", "snippet"); } } Log.d(Constants.DEBUG_TAG_MAPS, "completing map - END"); } @Override protected boolean isRouteDisplayed() { return false; } public void onLocationChanged(Location loc) { } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } public boolean onTouch(View v, MotionEvent event) { return false; } public void onMove(MapView mapView, GeoPoint center, boolean stopped) { if(!mytask.isCancelled()){ Log.d(Constants.DEBUG_TAG_MAPS, "async task is cancelling - ATTEMPT"); mytask.cancel(true); System.gc(); } if(stopped){ Log.d(Constants.DEBUG_TAG_MAPS, "finished move/zoom action"); Integer latspan = mv.getLatitudeSpan(); Integer lonspan = mv.getLongitudeSpan(); Integer maxlat = center.getLatitudeE6() + (latspan/2); Integer maxlon = center.getLongitudeE6() + (lonspan/2); Integer minlat = center.getLatitudeE6() - (latspan/2); Integer minlon = center.getLongitudeE6() - (lonspan/2); mytask = new MyTask(); mytask.execute(this, null, new ResultComposite()); } } public MapRectangle getRectangle(){ GeoPoint center = mv.getMapCenter(); Integer latspan = mv.getLatitudeSpan(); Integer lonspan = mv.getLongitudeSpan(); Integer maxlat = center.getLatitudeE6() + (latspan/2); Integer maxlon = center.getLongitudeE6() + (lonspan/2); Integer minlat = center.getLatitudeE6() - (latspan/2); Integer minlon = center.getLongitudeE6() - (lonspan/2); return new MapRectangle(maxlat, maxlon, minlat, minlon); } @Override public void completeAction(ResultComposite result) { Log.d(Constants.DEBUG_TAG_MAPS, "async tasc is going to complete in caller activity - OK"); if(result!=null){ advertResult.setAdvertSimpleList(result.getAdvertSimpleList()); completeMap(); } } @Override public RequestParams getRequestParams() { RequestParams params = new RequestParams(); params.setDb(db); params.setRectangle(getRectangle()); return params; } private class MyTask extends AsyncTask{ public MyMapActivity ma; public HttpClient httpclient; @Override protected ResultComposite doInBackground(Object... params) { Log.d(Constants.DEBUG_TAG_MAPS, "async tasc do in backgrounf - START"); ma = (MyMapActivity) params[0]; ResultComposite rc = new ResultComposite(); RequestParams rp = ma.getRequestParams(); MapRectangle rectangle = rp.getRectangle(); RequestJSONObject ro = new RequestJSONObject(rectangle.getMinlat(), rectangle.getMinlon(), rectangle.getMaxlat(), rectangle.getMaxlon()); Gson gson = new Gson(); String json = gson.toJson(ro); ResponseJSONObject responseJSONObject = getHttpContent(json, Constants.HTTP_REQUEST_MAP); AdvertSimpleJSON[] AdvertSimpleJSONarray = responseJSONObject.getAdvertySimple(); List simples = DataHelper.convertAdvertSimpleJSONArray2AdvertSimpleList(rp.getDb(), AdvertSimpleJSONarray); rc.setAdvertSimpleList(simples); return rc; } @Override protected void onPostExecute(ResultComposite result) { super.onPostExecute(result); Log.d(Constants.DEBUG_TAG_MAPS, "async tasc is going to complete in caller activity - ATTEMPT"); ma.completeAction(result); } @Override protected void onCancelled() { super.onCancelled(); Log.d(Constants.DEBUG_TAG_MAPS, "async task is cancelling - OK"); } private ResponseJSONObject getHttpContent(String json, String requestType){ ResponseJSONObject responseJSONObject = null; HttpPost post = new HttpPost(Constants.SERVER_MAP_URL); try { Log.d(Constants.DEBUG_TAG_MAPS, "try"); HttpEntity entity = new StringEntity(json); post.setEntity(entity); HttpParams httpParameters = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParameters, 15000); HttpConnectionParams.setSoTimeout(httpParameters, 150000); httpclient = new DefaultHttpClient(httpParameters); BasicHttpResponse response = (BasicHttpResponse ) httpclient.execute(post); if(response.getStatusLine().getStatusCode() == 200){ Log.d(Constants.DEBUG_TAG, "response 200"); HttpEntity responseEntity = response.getEntity(); Gson g = new Gson(); BufferedReader reader = new BufferedReader ( new InputStreamReader ( responseEntity.getContent()) ); responseJSONObject = g.fromJson(reader, ResponseJSONObject.class); reader.close(); System.gc(); } } catch (Exception e) { e.printStackTrace(); } Log.d(Constants.DEBUG_TAG_MAPS, "returning http results"); return responseJSONObject; } } }
What else should I do? I have tried to perform consume http entity.
Is my logic with handling AsynTask correct?