我有一个查找用户位置(MyLocation 类)的活动,然后使用或不使用地理点运行 AsyncTask 以连接到服务器并从我的服务器获取城市列表。当列表准备好时,它将它们保存在 ArrayList 城市中。一旦城市 ArrayList 被填满,我希望它被保存好(证明配置更改)。CityItem 实现 Parcelable。我将它们保存在 onSaveInstanceState 中并在 onCreate 中检索它们。
现在,如果任务已完成且城市列表已填满,则一切正常。然后我来回旋转我的设备和 Log.i("StartActivity", "Cities list added:"+cities.toString()); 被调用。
但是,如果我在找到地理点之前旋转设备(或任务完成 - 很难说,因为它发生得很快),那么
public void gotCities(ArrayList<CityItem> _cities){
cities = _cities;
Log.i("StartActivity", "gotCities("+cities.size()+"): "+cities.toString());
}
被调用(并且城市在日志中非常好)但是当我再次旋转它时ArrayList 城市似乎再次为空。
看来,如果配置更改并且 savedInstanceState.cities 为空,则 ArrayList 城市会以某种方式再次创建,并且它与 gotCities() 函数中的 ArrayList 不同。
我很确定这很容易,但我一直在寻找答案几个小时,但我根本做不到。
活动代码:
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;
}
从 AsyncTask onPostExecute 调用 gotCities() 方法:
@Override
protected void onPostExecute(Void result) {
if(this.activity!=null){
((StartActivity) activity).gotCities(cities);
}
}