我的搜索字段中包含“近邻位置”复选框和列表视图以显示结果。我现在处于活动的生命周期中,实现onSaveInstanceState和onRestoreInstanceState方法。当活动被销毁并且我回到它时,带有结果的列表视图已经消失,但是搜索框中的文本和复选框状态都被恢复,而我还没有在onSaveInstanceState中保存任何内容。为什么?什么是“自动”保存,我需要在onSaveInstanceState中保存什么?
public class Atable extends Activity {
private EditText mSearch;
private static final int ACTIVITY_EDIT=0;
private Button mSearchButton;
private TextView mNoresults;
private TextView mytext;
private ListView lv;
private CheckBox checkBox;
private LocationManager locationManager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv= (ListView)findViewById(R.id.listview);
mNoresults = (TextView) findViewById(R.id.noresults);
mNoresults.setVisibility(View.GONE);
mSearchButton = (Button)this.findViewById(R.id.button);
checkBox = (CheckBox) findViewById(R.id.local_check);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
mSearchButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mNoresults.setVisibility(View.GONE);
mSearch = (EditText) findViewById(R.id.search);
String tmp_str = mSearch.getText().toString().replace(" ","+");
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
String url = "http://www.atable.org/getRestaurantByQuery/?query=" + tmp_str;
if (checkBox.isChecked()) {
//get location
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
if (location!=null) {
String lat = String.valueOf(location.getLatitude());
String lng = String.valueOf(location.getLongitude());
url += "&lat="+lat+"&lng="+lng;
}
}
HttpGet httpget = new HttpGet(url);
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
Reader r = new InputStreamReader(instream);
Gson gson = new Gson();
final RestaurantList restaurantList = gson.fromJson(r, RestaurantList.class);
int nResults = restaurantList.getSize();
if (nResults>0) {
lv.setVisibility(View.VISIBLE);
lv.setAdapter( new ArrayAdapter<String>(Atable.this ,android.R.layout.simple_list_item_1,restaurantList.getRestaurantNames()));
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(Atable.this, RestaurantDescription.class);
Restaurant tmp_resto = restaurantList.getRestaurant((int)id);
String tmp_categories = tmp_resto.getCategories().get(0);
for (int i=1; i<tmp_resto.getCategories().size(); i++) {
tmp_categories+=", "+tmp_resto.getCategories().get(i);
}
String address = tmp_resto.getStreet()+", "+tmp_resto.getStreetNumber()+"\n"+tmp_resto.getCity()+
" "+tmp_resto.getPostalCode()+"\n"+tmp_resto.getCountry();
intent.putExtra("name", tmp_resto.getName());
intent.putExtra("address", address);
intent.putExtra("rating", tmp_resto.getRating());
intent.putExtra("price_range", tmp_resto.getPriceRange());
intent.putExtra("categories", tmp_categories);
intent.putExtra("latitude", tmp_resto.getLatitude());
intent.putExtra("longitude", tmp_resto.getLongitude());
startActivityForResult(intent, ACTIVITY_EDIT);
}
});
}
else {
lv.setVisibility(View.GONE);
mNoresults.setVisibility(View.VISIBLE);
}
//Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
//Start a location listener
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location loc) {
//sets and displays the lat/long when a location is provided
/*String latlong = "Lat: " + loc.getLatitude() + " Long: " + loc.getLongitude();
mytext.setText(latlong);*/
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
// required for interface, not used
}
};
//pauses listener while app is inactive
@Override
public void onPause() {
super.onPause();
locationManager.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
@Override
public void onResume() {
super.onResume();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,onLocationChange);
}
@Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Activity is getting killed", Toast.LENGTH_LONG).show();
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Toast.makeText(this, "onRestoreInstanceState", Toast.LENGTH_LONG).show();
super.onRestoreInstanceState(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Toast.makeText(this, "onSaveInstanceState", Toast.LENGTH_LONG).show();
super.onSaveInstanceState(outState);
}
}
答案 0 :(得分:2)
首先,不要在UI线程上执行网络请求。您将在操作期间使用户无需响应,并有可能触发ANRs。请考虑使用AsyncTask
来查询您的服务器。
默认情况下,活动保存并恢复其视图层次结构状态。每个View
的实现负责决定应保存和恢复其状态的哪些部分。 ListView
像往常一样是个特例。
ListView
确实保存了关于当前列表位置和项目选择的状态,但如果没有适配器,所有这些都是无用的。如果在Activity#onRestoreInstanceState
中恢复保存的视图层次结构状态之前设置适配器,ListView
将尝试将其视图状态与数据重新同步。
调用onSaveInstanceState
并且您有结果数据可用时,您可以将保存的搜索结果写入您提供的Bundle
。
在onCreate
中,检查提供的Bundle
是否不是null
,以及您之前的查询中是否包含您的数据。如果是,请将其读回。使用它构建新适配器并在setAdapter
上调用ListView
。 ListView
应该从那里开始。