Android观察者模式

在开发天气app的过程中,需要随时从网络获取最新的天气情况,并且获取完天气数据之后要更新UI,但是网络请求是耗时操作,主线程不可能等着网络加载结束之后获取数据,并且因为多个地方都要根据天气情况进行更新,因此这个时候用观察者模式是最合适的了。
获取天气的类就属于被观察者,需要更新天气的地方就是观察者,所以我们首先要定义接口、被观察者类,然后在需要地方添加观察者

import java.util.List;

public interface WeatherDataListener {
    void onWeatherDataLoaded(List<WeatherInfo> weatherInfoList);
}
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public class Weather {
    private String cityName;//对外的接口,城市名称
    //记录当前界面需要信息,日期、天气,最高温度、最低温度
    private List<WeatherInfo> weatherInfoList = new ArrayList<>();//weatherInfoList 是一个存放了日期、天气,最高温度、最低温度的类

    private String wea_URL_head="********";//用于根据城市名称拼凑对应天气接口URL,处于保密这里就没有公开,你可以在和风天气上申请一个接口账号

    private List<WeatherDataListener> listenerList;//存放所有的观察者,在需要回调的时候轮询就可以
    //在观察者new了天气类和重载了接口方法之后,需要将当前观察加入到观察队列中
    public void addWeatherDataListener(WeatherDataListener listener) {
        if(listenerList == null)
            listenerList = new ArrayList<>();
        listenerList.add(listener);
    }

    //请求城市的三天天气,并更新
    public void requestWeather(String cityName) {
        this.cityName=cityName;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(weatherUrl());
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.connect();
                    InputStream in = connection.getInputStream();
                    BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
                    StringBuilder builder = new StringBuilder();
                    String s;
                    if ((s = buffer.readLine()) != null)
                        builder.append(s);
                    parseData(builder.toString());
                    //weatherDataListener.onWeatherDataLoaded(weatherInfoList);
                    for(WeatherDataListener w : listenerList) {
                        w.onWeatherDataLoaded(weatherInfoList);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 将中文名称的城市转换为对应的天气接口
     * @param paramString城市名称,例如“深圳”
     */
    private String weatherUrl() {
        String name =toURLEncoded(cityName);
        return (wea_URL_head+name);
    }
     /**
     * 将中文汉字转化为url
     */
    private static String toURLEncoded(String paramString) {
        if (paramString == null || paramString.equals("")) {
            return "";
        }
        try
        {
            String str = new String(paramString.getBytes(), "UTF-8");
            str = URLEncoder.encode(str, "UTF-8");
            return str;
        }
        catch (Exception localException)
        {
            localException.printStackTrace();
        }
        return "";
    }

    /**
     * 将GSON格式的String进行解析,并放入weather中
     * @param s
     */
    private void parseData(String s) {
        try {
            JSONObject jsonObject = new JSONObject(s);
            JSONArray array = jsonObject.getJSONArray("days");
            for (int i = 0; i < 3; i++) {
                JSONObject day = array.getJSONObject(i);
                WeatherInfo info = new WeatherInfo();
                info.date = day.getString("date");
                info.weatherCondition = day.getString("Weather");
                info.maxDegree = day.getInt("MaxDegree");
                info.minDegree = day.getInt("MinDegree");
                weatherInfoList.add(info);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

接下来就是在需要更新天气的地方设置观察者了

		Weather weather=new Weather();
        WeatherDataListener weatherDataListener=new WeatherDataListener() {
            @Override
            public void onWeatherDataLoaded(List<WeatherInfo> weatherInfoList) {
                //获得天气数据之后的操作
                Log.d("weatherInfoList",weatherInfoList.get(0).weatherCondition);
            }
        };
        weather.addWeatherDataListener(weatherDataListener);
        weather.requestWeather(cityName);

搞定!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值