本文出自EzraZhao扎酷,轉(zhuǎn)載請(qǐng)注明出處檐涝。
本篇文章只適合剛?cè)腴T(mén)菜鳥(niǎo),大神級(jí)請(qǐng)繞道法挨,謝謝谁榜。
廢話不多說(shuō),相信大家有不少人都在學(xué)習(xí)或者學(xué)過(guò)郭霖郭大神的第一行代碼凡纳,本人在學(xué)習(xí)第二版時(shí)窃植,在制作酷歐天氣中發(fā)現(xiàn)一個(gè)小bug,不知道大家有沒(méi)有發(fā)現(xiàn)。
在你啟動(dòng)郭神的應(yīng)用后荐糜,現(xiàn)在假如已經(jīng)加載了一個(gè)城市的天氣信息巷怜,然后你進(jìn)行切換城市操作,然后進(jìn)行刷新操作狞尔,哎丛版,你會(huì)發(fā)現(xiàn)城市竟然又切回了啟動(dòng)時(shí)的城市天氣,而且不管你切換幾次偏序,只要一刷新页畦,就會(huì)切回原來(lái)的。
這個(gè)小bug在我做完隨意切換城市時(shí)發(fā)現(xiàn)的研儒。然后進(jìn)行一番調(diào)試豫缨,發(fā)現(xiàn)問(wèn)題的根源在于WeatherActivity的onCreate()方法
final String weatherId;
if (weatherString != null) {
//有緩存時(shí)直接解析天氣數(shù)據(jù)
Weather weather = Utility.handleWeatherResponse(weatherString);
weatherId = weather.basic.weatherId;
showWeatherInfo(weather);
} else {
//無(wú)緩存時(shí)去服務(wù)器查詢(xún)天氣
weatherId = getIntent().getStringExtra("weather_id");
//請(qǐng)求數(shù)據(jù)時(shí)先將ScrollView隱藏,否則空界面看上去會(huì)比較奇怪
weatherLayout.setVisibility(View.INVISIBLE);
requestWeather(weatherId);
}
不知道你發(fā)現(xiàn)問(wèn)題沒(méi)端朵,如果沒(méi)有發(fā)現(xiàn)好芭,好,讓我們一起來(lái)回想一下Activity的生命周期冲呢,還記得onCreate()方法只會(huì)在Activity創(chuàng)建時(shí)執(zhí)行一次嗎舍败?明白沒(méi),對(duì)了,就是這個(gè)問(wèn)題邻薯,咱們的weatherId只會(huì)在WeatherActivity創(chuàng)建時(shí)被加載一次裙戏,也就是說(shuō)當(dāng)你啟動(dòng)應(yīng)用后,咱們的應(yīng)用會(huì)默認(rèn)加載一次天氣厕诡,如果你是第一次安裝累榜,那么就會(huì)從服務(wù)器加載,沒(méi)問(wèn)題灵嫌,如果你是已經(jīng)打開(kāi)過(guò)壹罚,會(huì)從緩存加載,沒(méi)問(wèn)題寿羞。然后你切換一次城市猖凛,哎,問(wèn)題來(lái)了稠曼,由于咱們的WeatherActivity創(chuàng)建完了形病,然后weatherId就不會(huì)再更改了,所以咱們的
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
requestWeather(weatherId);
}
});
這個(gè)方法每次傳入的id都是在Activity創(chuàng)建時(shí)的同一個(gè)霞幅,一刷新當(dāng)然會(huì)改回去咯。
然而這個(gè)小bug怎么解決呢量瓜?so easy,weatherId不是不變么司恳,來(lái),咱們來(lái)解決一下:
先提供一種簡(jiǎn)單的方案:
哦绍傲,requestWeather(String weatherId)這個(gè)這個(gè)里面的id每次都是新的扔傅,那咱們就把weatherId從onCreate()方法中拿出去,變成全局變量烫饼,然后在requestWeather(String weatherId)這個(gè)方法中更新一下猎塞,
public void requestWeather(String weatherId) {
String weatherUrl = "http://guolin.tech/api/weather?cityid="
+ weatherId + "&key=" + API_KEY;
//使weatherId成為全局變量,在每一次請(qǐng)求時(shí)都更新當(dāng)前id
this.weatherId = weatherId;
...
}
就是這么簡(jiǎn)單杠纵,每次更新一下荠耽,解決!
咱們?cè)賮?lái)看一種不把weatherId變成全局變量的方法:
這個(gè)方法借助SharedPreferences將weatherId在選擇城市后進(jìn)行本地存儲(chǔ)一下比藻,來(lái)铝量,我們改一下ChooseAreaFragment這個(gè)類(lèi)中的代碼:
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();
//對(duì),改的就是這银亲!
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);
}
}
}
});
然而這樣完了嗎慢叨?當(dāng)然并沒(méi)有,我們只是存儲(chǔ)了务蝠,在WeatherActivity中還是只讀取了一次啊拍谐,下面我們?cè)賮?lái)改一下刷新時(shí)監(jiān)聽(tīng)器代碼:
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就是爽!
歡迎交流轩拨。