Как избежать OutOfMemory при попытке вызвать мой сервер и анализировать данные каждый раз, когда я перехожу на карту - PullRequest
0 голосов
/ 20 января 2012

У меня есть MyMapActivity с закрытым классом, расширяющим AsyncTask с целью выполнения запроса на сервере каждый раз, когда изменяется раздел карты (метод onMove ()). Ответ от сервера - строка данных JSON, которая может быть около 1-3 МБ. Поэтому мне нужно избегать многократных обращений к серверу, когда пользователь перемещает карту, чтобы избежать OutOfMemory. По этой причине я пытаюсь проверить, отменяется ли мой собственный AsyncTask (при каждом запуске onMove ()), и если нет (полагаю, это указывает на выполнение метода doInBackground ()), я пытаюсь отменить его. Но независимо от этого у меня все еще есть

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 

Вот мой класс активности:

</p> <pre> 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; } } } </pre> <p>

Что еще мне делать? Я пытался выполнить потреблять http сущности.

Правильна ли моя логика работы с AsynTask?

...