У меня есть acitivty, который ищет местоположение пользователя (класс MyLocation), затем с геопунктом или без него запускается AsyncTask для соединения с сервером и получения списка городов с моего сервера. Когда список готов, он сохраняет их в городах ArrayList. Как только ArrayList городов заполнен, я бы хотел, чтобы он был сохранен навсегда (доказательство изменений конфигурации). CityItem реализует Parcelable. Я сохраняю их в onSaveInstanceState и извлекаю их при создании.
Теперь все работает нормально, если задание выполнено и список городов заполнен. Затем я поворачиваю свое устройство вперед и назад и Log.i («StartActivity», «Загружен список городов:» + towns.toString ()); вызывается.
Но если я поверну устройство до того, как будет найден геопункт (или задача выполнена - трудно сказать, потому что это происходит быстро), тогда
public void gotCities(ArrayList<CityItem> _cities){
cities = _cities;
Log.i("StartActivity", "gotCities("+cities.size()+"): "+cities.toString());
}
вызывается (и в журнале все отлично), но когда я поворачиваю его еще раз, ArrayList городов снова становится нулевым .
Похоже, что если конфигурация изменилась, а saveInstanceState.cities был равен нулю, города ArrayList каким-то образом снова создаются, и это не тот же ArrayList, что и в функции gotCities ().
Я почти уверен, что это легко, но я часами искал ответ и просто не могу этого сделать.
Код Деятельности:
public class StartActivity extends Activity {
public static final String PREFS_NAME = "PrefsFile";
MyLocation myLocationObject = null;
LatLngPoint point = null;
ArrayList<CityItem> cities = null;
FindCityTask task = null;
Activity startActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
if(savedInstanceState!=null) if(savedInstanceState.containsKey("cities")) cities = savedInstanceState.getParcelableArrayList("cities"); if(cities!=null) Log.i("Cities retrieved", cities.toString());
super.onCreate(savedInstanceState);
startActivity = this;
setContentView(R.layout.start);
//check if the configuration (orientation) has been changed
NonConfigurationObject nco = (NonConfigurationObject)getLastNonConfigurationInstance();
if(nco!=null) if(nco.myLocationObject!=null) myLocationObject = nco.myLocationObject;
if(nco!=null) if(nco.task!=null) task = nco.task;
if(cities==null){
Log.i("StartActivity", "Cities list is empty - retrieve them.");
if(myLocationObject==null){
getGeopoint();
}
} else {
Log.i("StartActivity", "Cities list downloaded:"+cities.toString());
}
}
private void getGeopoint(){
if(isOnline()){ //there is internet connection
if(myLocationObject==null){
myLocationObject = new MyLocation();
//calls function to check user location (returns false if no providers are enabled
if(!myLocationObject.getLocation(this, locationResult)){ /*TODO handle */Log.i("StartActivity", "Location providers disabled");}
}
} else { //not online - show msg
Log.i("StartActivity", "No internet connection");
}
}
//waits for user geopoint. then starts FindCityTask
LocationResult locationResult = new LocationResult(){
@Override
public void gotLocation(final Location location){
if(location!=null){
// location found
Log.i("StartActivity", "Received location: "+location.toString());
point = new LatLngPoint((float)location.getLatitude(), (float)location.getLongitude());
} else {
// location not found
Log.i("StartActivity", "No location received after 20 seconds");
point = null;
}
//RUN TASK to connect to server to get cities list (even if there's no geopoint)
task = new FindCityTask(startActivity);
task.execute(point);
}
};
public void gotCities(ArrayList<CityItem> _cities){
cities = _cities;
Log.i("StartActivity", "gotCities("+cities.size()+"): "+cities.toString());
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i("onSaveInstanceState", "onSaveInstanceState");
if(cities!=null) savedInstanceState.putParcelableArrayList("cities", cities);
}
@Override
public NonConfigurationObject onRetainNonConfigurationInstance() {
NonConfigurationObject nco = new NonConfigurationObject();
if(myLocationObject!=null){
nco.myLocationObject = myLocationObject;
}
if(task!=null){
nco.task = task;
}
return nco;
}
static class NonConfigurationObject{
MyLocation myLocationObject;
FindCityTask task;
}
Метод gotCities () вызывается из AsyncTask onPostExecute:
@Override
protected void onPostExecute(Void result) {
if(this.activity!=null){
((StartActivity) activity).gotCities(cities);
}
}