本文出自EzraZhao,轉載請注明出處。
本篇文章只適合剛入門菜鳥,大神級請繞道,謝謝。
廢話不多說,相信大家有不少人都在學習或者學過郭霖郭大神的第一行代碼,本人在學習第二版時,在制作酷歐天氣中發現一個小bug,不知道大家有沒有發現。
在你啟動郭神的應用后,現在假如已經加載了一個城市的天氣信息,然后你進行切換城市操作,然后進行刷新操作,哎,你會發現城市竟然又切回了啟動時的城市天氣,而且不管你切換幾次,只要一刷新,就會切回原來的。
這個小bug在我做完隨意切換城市時發現的。然后進行一番調試,發現問題的根源在于WeatherActivity的onCreate()方法
final String weatherId;
if (weatherString != null) {
//有緩存時直接解析天氣數據
Weather weather = Utility.handleWeatherResponse(weatherString);
weatherId = weather.basic.weatherId;
showWeatherInfo(weather);
} else {
//無緩存時去服務器查詢天氣
weatherId = getIntent().getStringExtra("weather_id");
//請求數據時先將ScrollView隱藏,否則空界面看上去會比較奇怪
weatherLayout.setVisibility(View.INVISIBLE);
requestWeather(weatherId);
}
不知道你發現問題沒,如果沒有發現,好,讓我們一起來回想一下Activity的生命周期,還記得onCreate()方法只會在Activity創建時執行一次嗎?明白沒,對了,就是這個問題,咱們的weatherId只會在WeatherActivity創建時被加載一次,也就是說當你啟動應用后,咱們的應用會默認加載一次天氣,如果你是第一次安裝,那么就會從服務器加載,沒問題,如果你是已經打開過,會從緩存加載,沒問題。然后你切換一次城市,哎,問題來了,由于咱們的WeatherActivity創建完了,然后weatherId就不會再更改了,所以咱們的
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
requestWeather(weatherId);
}
});
這個方法每次傳入的id都是在Activity創建時的同一個,一刷新當然會改回去咯。
然而這個小bug怎么解決呢?so easy,weatherId不是不變么,來,咱們來解決一下:
先提供一種簡單的方案:
哦,requestWeather(String weatherId)這個這個里面的id每次都是新的,那咱們就把weatherId從onCreate()方法中拿出去,變成全局變量,然后在requestWeather(String weatherId)這個方法中更新一下,
public void requestWeather(String weatherId) {
String weatherUrl = "http://guolin.tech/api/weather?cityid="
+ weatherId + "&key=" + API_KEY;
//使weatherId成為全局變量,在每一次請求時都更新當前id
this.weatherId = weatherId;
...
}
就是這么簡單,每次更新一下,解決!
咱們再來看一種不把weatherId變成全局變量的方法:
這個方法借助SharedPreferences將weatherId在選擇城市后進行本地存儲一下,來,我們改一下ChooseAreaFragment這個類中的代碼:
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (currentLevel == LEVEL_PROVINCE) {
selectedProvince = provinceList.get(position);
queryCities();
} else if (currentLevel == LEVEL_CITY) {
selectedCity = cityList.get(position);
queryCounties();
} else if (currentLevel == LEVEL_COUNTY) {
String weatherId = countyList.get(position).getWeatherId();
if (getActivity() instanceof MainActivity) {
Intent intent = new Intent(getActivity(), WeatherActivity.class);
intent.putExtra("weather_id", weatherId);
startActivity(intent);
getActivity().finish();
} else if (getActivity() instanceof WeatherActivity) {
WeatherActivity activity = (WeatherActivity) getActivity();
//對,改的就是這!
SharedPreferences.Editor editor =
PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this)
.edit();
editor.putString("weather_id", weatherId);
editor.apply();
activity.drawerLayout.closeDrawers();
activity.swipeRefresh.setRefreshing(true);
activity.requestWeather(weatherId);
}
}
}
});
然而這樣完了嗎?當然并沒有,我們只是存儲了,在WeatherActivity中還是只讀取了一次啊,下面我們再來改一下刷新時監聽器代碼:
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(WeatherActivity.this);
String temp = prefs.getString("weather_id", weatherId);
requestWeather(temp);
}
});
是不是也是so easy,
我們跑一下吧~
(@ο@) 哇哈哈哈~改完bug就是爽!
歡迎交流。