酷歐天氣bug

源碼地址

本文出自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就是爽!

歡迎交流。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,368評論 25 708
  • 1.什么是Activity?問的不太多,說點有深度的 四大組件之一,一般的,一個用戶交互界面對應一個activit...
    JoonyLee閱讀 5,760評論 2 51
  • 哎呀呀 ,馬上就要面臨找工作了,媛媛心里緊張呀. 作為一個即將畢業的Android程序媛,開始面臨找工作了,...
    左神話閱讀 4,865評論 7 59
  • 今天本來計劃早早睡下,明天元氣滿滿的上班.可是正在計劃睡覺的時候,離我2米遠的工作號手機鈴聲傳來,不用想我都知道是...
    天然美閱讀 964評論 0 0
  • 每天都要到很晚才愿意入睡,熬到極點才讓自己身心俱疲地閉上眼。物理層面的消耗,自虐不過如此。其實,是開學焦慮。 想想...
    _莫閑閱讀 170評論 0 0