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

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

01-19 20:45:05.660: ОШИБКА /MapActivity(2482): не удалось получить клиент фабрики соединений
01-19 20:45:40.600: ОШИБКА / Модем (96): активный iface (usb0) сообщается как добавленный, игнорируя
01-19 20:47:15.260: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 11908 байт.
01-19 20: 47: 15.270: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =23091 КБ, Размер растрового изображения =101 КБ
01-19 20: 47: 15.410: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти на 7690-байтовом выделении.
01-19 20: 47: 15.420: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =23088 КБ, Размер растрового изображения =101 КБ
01-19 20: 47: 15.570: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 7656 байт.
01-19 20: 47: 15.590: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =23090 КБ, Размер растрового изображения =101 КБ
01-19 20:47:15.730: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 9098 байт.
01-19 20: 47: 15.740: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =23097 КБ, Размер растрового изображения =101 КБ
01-19 20: 48: 01.850: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 8176 байт.
01-19 20: 48: 01.850: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =22767 КБ, Размер растрового изображения =101 КБ
01-19 20: 48: 01.970: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 12022 байта.
01-19 20: 48: 01.980: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =22768 КБ, Размер растрового изображения =101 КБ
01-19 20: 48: 02.110: ОШИБКА /dalvikvm-heap(2482): Недостаточно памяти при выделении 8936 байт.
01-19 20: 48: 02.119: ОШИБКА /dalvikvm(2482): Недостаточно памяти: Размер кучи =24519 КБ, Выделено =22769 КБ, Размер растрового изображения =101 КБ
01-19 20:48:07.220: WARN/dalvikvm(2482): threadid=20: выход из потока с необработанным исключением (группа =0x400259f8)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: AsyncTask #9
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): java.lang.RuntimeException: произошла ошибка при выполнении doInBackground()
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на android.os.AsyncTask$3.done(AsyncTask.java:200)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): по адресу java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.lang.Thread.run(Thread.java:1102)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): вызвано: java.lang.OutOfMemoryError
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.lang.String.(String.java:468)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.lang.StringBuilder.toString(StringBuilder.java:664)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.stream.JsonReader.nextString(JsonReader.java:995)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.stream.JsonReader.nextValue(JsonReader.java:810)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.stream.JsonReader.objectValue(JsonReader.java:790)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.stream.JsonReader.quickPeek(JsonReader.java:385)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.stream.JsonReader.peek(JsonReader.java:348)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:322)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:334)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): в com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:170)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): в com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:38)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:71)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): в com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:170)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.Gson.fromJson(Gson.java:720)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на com.google.gson.Gson.fromJson(Gson.java:660)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): по адресу net.amagumo.realestate.MyMapActivity$MyTask.getHttpContent(MyMapActivity.java:444)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): в net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:393)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482):     at net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:1)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на android.os.AsyncTask$2.call(AsyncTask.java:185)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482): на java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-19 20:48:07.350: ОШИБКА /AndroidRuntime(2482):     ... еще 4
01-19 20:48:07.450: WARN/ActivityManager(96): принудительное завершение деятельности net.amagumo.realestate/.MyMapActivity
01-19 20:48:21.290: WARN/TimeThread(294): ошибка преобразования времени
01-19 20:48:42.899: WARN/TimeThread(294): ошибка преобразования времени 

Вот мой класс деятельности:

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;
        } 



    }
}


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

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

0 ответов

Другие вопросы по тегам