Странное поведение активности на разных версиях андроида: моргает карта

У меня есть действие, которое отображает карту Google с некоторой дополнительной информацией. Также у меня есть служба, которая загружает информацию с сервера и периодически информирует активность о том, что другая часть информации загружается с использованием PendingIntent.
На Android 4.0.3 все работает нормально. Но на Android 2.3.4 карта в активности мигает (становится серым, а затем перезагружается) каждый раз, когда сервис сообщает об этой активности.
Попытался отследить, обновляется ли карта где-нибудь в onActivityResult, но это не так.
Любая помощь приветствуется. Вот код:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == SERVICE_CACHED) {
        String fmId = data.getStringExtra("cachedId");
        if (dev.get(position).getId().equals(fmId)) {   //we still viewing the same device
            long[] dat = data.getLongArrayExtra("dates");
            ArrayList<Date> dates = new ArrayList<Date>();
            for (int i=0; i<dat.length; i++) {
                dates.add(new Date(dat[i]));
            }

            addDates(fmId, dates, false, true);

//this is executed only once, as it meant to be
            if ((dispDate.getText() == null) || (dispDate.getText().toString().isEmpty())) {
                State state;
                synchronized(DBHelper.class) {
                    state = DBHelper.getState(fmId, dates.get(0).getTime());
                }


                updDispState(state);
            }
        }
    }
}


public void addDates(String fmId, ArrayList<Date> dates, boolean clear, boolean addTimesTo0) {
    if (dev.get(position).getId().equals(fmId)) {   //maybe user already changed selected device
        if (clear) {
            this.dates = dates;
        } else {
            this.dates.addAll(0, dates);
        }
        updDateSpinners(clear, dates, addTimesTo0);
    }
}

Сервис информирует об активности, используя это:

private void cache(LinkedList<State> statsAll, LinkedList<Long> datesAll) {
        if ((statsAll == null) || (statsAll.isEmpty()) || (datesAll == null) || (datesAll.isEmpty())) {
            return;
        }

        synchronized(DBHelper.class) {
            DBHelper.addStates(statsAll, fmId);
        }
        //inform MapActivity that new data is available
        long[] l = new long[datesAll.size()];
        for (int i=0; i<l.length; i++) {
            l[i] = datesAll.get(i);
        }
        Intent intent = new Intent().putExtra("cachedId", fmId).putExtra("dates", l);
        try {
            pi.send(CacheService.this, MapActivity.SERVICE_CACHED, intent);
        } catch (PendingIntent.CanceledException e) {}          
    }

ОБНОВЛЕНИЕ
Проведя еще несколько тестов, я обнаружил, что карта просто перезагружается при каждом вызове onResume(). Как это остановить?
Я помещаю карту в xml следующим образом:

<fragment             
    android:id="@+id/mapF"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.SupportMapFragment" /> 

И получить его в коде позже

GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapF)).getMap();    

person Natalia    schedule 19.06.2013    source источник
comment
вы переопределяете onConfigurationChange? не могли бы вы предоставить коды для updDispState(), updDateSpinners() и любого другого места, где вы обновляете свою карту или дисплей   -  person tony m    schedule 01.07.2013


Ответы (2)


Вы не должны использовать onActivityResult таким образом из службы. Попробуйте вместо этого использовать BroadcastReceiver. Ваш класс Activity должен зарегистрировать слушателя широковещательной рассылки, а ваш класс Service должен отправлять широковещательную рассылку Intent при появлении новой информации.

person twaddington    schedule 02.07.2013
comment
не уверен, о чем вы говорите, потому что я отправляю ожидающее намерение обратно в активность из службы, когда информация доступна. - person Natalia; 03.07.2013
comment
Когда вы отправляете PendingIntent, будут вызываться методы жизненного цикла вашей активности, это вызывает странное поведение с вашим MapFragment. Использование BroadcastReceiver позволит вашему Activity продолжать бесперебойную работу и по-прежнему получать результаты из вашего фона Service. Используйте метод sendBroadcast из вашего Service и реализуйте приемник в своем классе Activity. - person twaddington; 03.07.2013
comment
Хорошо, спасибо за ваш ответ, я попробую этот подход и приму ваш ответ, если он сработает. Но моя награда куда-то пропала(( - person Natalia; 04.07.2013
comment
Действительно, вы спасатель! Я думал, что не смогу пройти через это. Есть ли способ назначить вам награду? - person Natalia; 04.07.2013
comment
Вы приняли мой ответ, и это нормально. Вы также можете проголосовать за мой ответ. На самом деле, я просто рад, что это было полезно для вас. Удачи! - person twaddington; 05.07.2013

У меня похожая проблема, когда я перемещаю карту (показывая меню) в Android 4.0, все работает нормально, но в 2.3 происходит то, что вы сказали. Я ничего не мог сделать, чтобы исправить это, поэтому моим решением было использовать относительную компоновку и отображать информацию перед картой. Я думаю, что в "старых версиях" андроида карта не оптимизирована для обновления в фоновом режиме и именно поэтому он становится черным и обновляется.

person ƒernando Valle    schedule 02.07.2013
comment
как вы обновляете свой относительный макет, когда карта перемещается или изменяется масштаб? Мне нужно нарисовать круг на карте, который должен оставаться с теми же координатами и радиусом в метрах, что бы ни случилось с картой. - person Natalia; 03.07.2013
comment
Вы говорите об изменении внутри карты, рисующей наложение? - person ƒernando Valle; 03.07.2013
comment
когда вы добавляете оверлей, он запускается в потоке пользовательского интерфейса, поэтому я думаю, что вы ничего не можете с ним поделать, но вы можете попробовать с помощью AsyncTask обработать информацию и после этого показать ее на карте. более или менее здесь есть пример stackoverflow.com/questions/8744573/ - person ƒernando Valle; 03.07.2013
comment
нет, это не то, что я имел в виду. Мои элементы наложения мигают вместе с картой при каждом вызове onResume(). Вы предложили использовать относительную компоновку вместо наложения (если я правильно вас понял). Таким образом, карта все равно будет мигать, а макет — нет. Но если пользователь увеличит или уменьшит масштаб карты, все круги, отображаемые в макете, станут неправильными. - person Natalia; 03.07.2013