사용자 위치 (MyLocation 클래스)를 찾는 acitivty가 있고 geopoint가 있거나없는 경우 AsyncTask를 실행하여 서버에 연결하고 내 서버에서 도시 목록을 가져옵니다. 목록이 준비되면 ArrayList 도시에 저장할 수 있습니다. 일단 도시 ArrayList가 채워지면 (배열 변경에 대한 증명) 좋은 결과를 위해 저장되기를 바랍니다. CityItem은 Parcelable을 구현합니다. onSaveInstanceState에 저장하고 onCreate에서 검색합니다.구성 변경 후 변수에 대한 참조가 손실되었습니다.
이제 작업이 완료되고 도시 목록이 채워지면 모든 것이 올바르게 작동합니다. 그런 다음 장치를 앞뒤로 돌리고 Log.i ("StartActivity", "도시 목록 다운로드 :"+ cities.toString()); 호출됩니다. 다음,
public void gotCities(ArrayList<CityItem> _cities){
cities = _cities;
Log.i("StartActivity", "gotCities("+cities.size()+"): "+cities.toString());
}
가 호출되는 (과 도시 완벽하게 괜찮 - GeoPoint의이을 발견 (하드가 빨리 발생하기 때문에 말하거나 작업 완료) 전에
그러나 나는 장치 를 회전하는 경우 로그에서)하지만 다시 한 번 회전하면 ArrayList 도시가 다시 null로 나타납니다.
구성이 변경되고 savedInstanceState.cities가 null 인 경우 ArrayList 도시가 어떻게 든 다시 만들어지고 getCities() 함수와 동일한 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;
}
gotCities() 메소드가 AsyncTask를 onPostExecute에서 호출됩니다
@Override
protected void onPostExecute(Void result) {
if(this.activity!=null){
((StartActivity) activity).gotCities(cities);
}
}
하지만 onSaveInstanceState의 콜백이 있으므로 호출됩니다. 위치 획득은 TimerTask로 이동합니다 (MyLocation이이를 처리하고 geopoint를 locationResult로 보냅니다). 나는 잠깐 전에 해결책을 찾았지만 괜찮은지 궁금해. –
정적 필드는 정상입니다. 앱 JVM만큼 오래 지속되며 활동 라이프 사이클의 영향을받지 않습니다. –
감사합니다. 그러나 나는 아직도 내가 뭔가를 놓치고 있다고 느낍니다. 나는 도시 변수가 단순히 유출되었다고 걱정한다. 그리고 나는 그것이 어디에서 일어 났는지 궁금해. –