[Android | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用
2016-09-22 20:39
986 查看
2016年9月22日 课上小练习,使用spinner选择地区。加载Assets/citycode.json中地区所对应代码。然后根据Api在线加载天气信息。很简单,重点在于Json对象与数组混合,分层解析就好。以及Volley框架的使用。
新增了源代码下载。
本App为小练习,所以使用了Spinner选择地区,而没有使用Activity来更好的显示。请忽略这一点。图片从墨迹天气里截取的。
在
其中
↑ 先创建一个
让我们看看json请求的数据
↑ 其中返回的response是三层json对象,
先判断第一层”desc” 是否为”ok”
第二层数据JSONObject解析”data”数据,然后再用
JSONObject jsonObject = response.optJSONObject(“data”);
Weather weather = gson.fromJson(jsonObject.toString(), Weather.class);
即可正确解析,但是这里有个坑。本APP使用的api,
第三层数据为数组。依然需要使用
然后就是设置view数据了
使用
源代码下载:传送门
新增了源代码下载。
本App为小练习,所以使用了Spinner选择地区,而没有使用Activity来更好的显示。请忽略这一点。图片从墨迹天气里截取的。
AndroidManifest.xml中 配置volley Application。会使用更方便些 ↓
<application android:name=".AppController" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> //...Activity 标签 <application/>
AppController简单封装volley ↓
/** * Created by lic on 2016/9/22. */ public class AppController extends Application { public static final String TAG = AppController.class .getSimpleName(); private RequestQueue mRequestQueue; private ImageLoader mImageLoader; private static AppController mInstance; @Override public void onCreate() { super.onCreate(); mInstance = this; } public static synchronized AppController getInstance() { return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } public ImageLoader getImageLoader() { getRequestQueue(); //如果不用图片加载,可以不写 if (mImageLoader == null) { mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache()); } return this.mImageLoader; } public <T> void addToRequestQueue(Request<T> req, String tag) { // set the default tag if tag is empty req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null) { mRequestQueue.cancelAll(tag); } } }
LruBitmapCachevolley图片加载类,如果不需要可以在上面注释掉 ↓
/** * Created by lic on 2016/9/22. */ public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache { public static int getDefaultLruCacheSize() { final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int cacheSize = maxMemory / 8; return cacheSize; } public LruBitmapCache() { this(getDefaultLruCacheSize()); } public LruBitmapCache(int sizeInKiloBytes) { super(sizeInKiloBytes); } @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } @Override public Bitmap getBitmap(String url) { return get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { put(url, bitmap); } }
MainActivity
SpinnAsync异步加载Spinner内容 ↓
public class SpinnAsync extends AsyncTask { private Context context; SpinnAsync(Context context) { this.context = context; } @Override protected Object doInBackground(Object[] params) { try { List<CityCode> result = new ArrayList<>(); InputStream in = context.getResources().getAssets().open("citycode.json"); int length = in.available(); byte[] buffer = new byte[length]; in.read(buffer); String line = new String(buffer); result = convertToBean(line); return result; } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Object o) { if (o == null) { Toast("发生未知错误"); return; } List<CityCode>list = (List<CityCode>)o; String[] cities=new String[list.size()]; for(int i=0;i<list.size();i++) cities[i]=list.get(i).getCity(); cityCodeList = list; ArrayAdapter adapter=new ArrayAdapter(context,android.R.layout.simple_spinner_item,cities); adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice); spinner.setAdapter(adapter); spinner.setSelection(getSpArg(),true); } }
其中
convertToBean方法
public List<CityCode> convertToBean(String json) { List<CityCode> result=new ArrayList<>(); try { JSONObject obj = new JSONObject(json); JSONArray jsons = obj.getJSONArray("城市代码"); for (int n = 0; n < jsons.length(); n++) { JSONObject sheng = jsons.getJSONObject(n); JSONArray shi = sheng.getJSONArray("市"); for (int i = 0; i < shi.length(); i++) { JSONObject rss = shi.optJSONObject(i); CityCode m = new CityCode(); m.setCode(rss.getString("编码")); m.setCity(rss.getString("市名")); result.add(m); } } }catch (JSONException e) { e.printStackTrace(); } return result; }
volley联网 分层解析json
public void startHttp(String code) { // Tag used to cancel the request String tag = "json_obj_weather"; String api = "http://wthrcdn.etouch.cn/weather_mini?citykey=%s"; String url = String.format(api, code); final ProgressDialog pDialog = new ProgressDialog(this); pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); pDialog.setMessage("加载中..."); pDialog.setCanceledOnTouchOutside(false); pDialog.show(); JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d(TAG, "Success--------------" + response.toString()); String result = null;//得到返回状态码 try { result = response.getString("desc"); if (result != null && result.equalsIgnoreCase("ok")) {//ok表示成功返回数据 JSONObject jsonObject = response.optJSONObject("data"); Gson gson = new Gson(); Weather weather = gson.fromJson(jsonObject.toString(), Weather.class); JSONArray jsonArray = jsonObject.optJSONArray("forecast"); if (jsonArray == null) { pDialog.dismiss(); return; } List<Forecast> fList = gson.fromJson(jsonArray.toString(), new TypeToken<List<Forecast>>(){}.getType()); setWeatherView(weather, fList); } } catch (JSONException e) { e.printStackTrace(); } pDialog.dismiss(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d(TAG, "Error--------------" + error.getMessage()); // hide the progress dialog pDialog.dismiss(); } } ); // Adding request to request queue AppController.getInstance().addToRequestQueue(jsonObjReq, tag); }
↑ 先创建一个
ProgressDialog,然后再用Volley直接
AppController.getInstance().addToRequestQueue(jsonObjReq, tag);就可以了很方便,不用考虑context。
让我们看看json请求的数据
{ "desc":"OK", "status":"1000", "data":{ "wendu":"21", "ganmao":"虽然温度适宜但风力较大,仍较易发生感冒,体质较弱的朋友请注意适当防护。", "forecast":[ { "fengxiang":"南风", "fengli":"4-5级", "high":"高温 24℃", "type":"晴", "low":"低温 18℃", "date":"22日星期四" }, { "fengxiang":"南风", "fengli":"4-5级", "high":"高温 24℃", "type":"多云", "low":"低温 19℃", "date":"23日星期五" }, { "fengxiang":"南风", "fengli":"4-5级", "high":"高温 25℃", "type":"多云", "low":"低温 18℃", "date":"24日星期六" }, { "fengxiang":"南风", "fengli":"4-5级", "high":"高温 25℃", "type":"晴", "low":"低温 19℃", "date":"25日星期天" }, { "fengxiang":"南风", "fengli":"4-5级", "high":"高温 24℃", "type":"小雨", "low":"低温 20℃", "date":"26日星期一" } ], "yesterday":{ "fl":"4-5级", "fx":"南风", "high":"高温 24℃", "type":"晴", "low":"低温 17℃", "date":"21日星期三" }, "aqi":"128", "city":"大连" } }
↑ 其中返回的response是三层json对象,
先判断第一层”desc” 是否为”ok”
第二层数据JSONObject解析”data”数据,然后再用
Gson,
JSONObject jsonObject = response.optJSONObject(“data”);
Weather weather = gson.fromJson(jsonObject.toString(), Weather.class);
即可正确解析,但是这里有个坑。本APP使用的api,
yesterday字段有的地区会为空。所以做好判断。
forecast字段为数组,需要再次解析。
第三层数据为数组。依然需要使用
Gson,
JSONArray jsonArray = jsonObject.optJSONArray("forecast"); if (jsonArray == null) { pDialog.dismiss(); return; } List<Forecast> fList = gson.fromJson(jsonArray.toString(), new TypeToken<List<Forecast>>(){}.getType());
然后就是设置view数据了
setWeatherView(weather, fList);
private void setWeatherView(Weather w, List<Forecast> list) { if (w == null && list.size()==0 ) { return; } Forecast f = list.get(0); tv_weather.setText(f.getType()); tv_tempera.setText(f.getHigh()+" ~ "+f.getLow()); tv_info.setText(w.getGanmao()); switch (f.getType()) { case "晴": rLayout.setBackgroundResource(R.drawable.bg_sunny_day); img1.setImageResource(R.drawable.w0); break; case "多云": rLayout.setBackgroundResource(R.drawable.bg_fog_and_haze); img1.setImageResource(R.drawable.w2); break; //.......... other case //省略不写了,详情查看源代码 default: if (f.getType().contains("霾")){ rLayout.setBackgroundResource(R.drawable.bg_fog_and_haze); img1.setImageResource(R.drawable.w20); } rLayout.setBackgroundResource(R.drawable.bg_na); img1.setImageResource(R.drawable.w45); break; } }
使用
SharedPreferences来存储城市信息,每次启动保持一致
/** 获取Preference Arg值 * */ private int getSpArg() { sp = getSharedPreferences("city_data", MODE_PRIVATE); return sp.getInt("arg", 0); } /** 获取Preference 城市代码值 * */ private String getSpCode() { sp = getSharedPreferences("city_data", MODE_PRIVATE); return sp.getString("code", "101010100"); } /**放置Preferences * */ private void pushPreferences(String code, int arg) { sp = getSharedPreferences("city_data", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("code", code); editor.putInt("arg", arg); editor.apply(); }
源代码下载:传送门
相关文章推荐
- Android JSON数据格式的解析,与简单对象、带泛型的List和Map的转换,以及GSON的使用
- Android开发-Volley-解析Json使用方法-3-完整Demo-AndroidStudio
- Android开发-Volley-解析Json使用方法-4-完整Demo-AndroidStudio
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- Android 使用Gson解析Json和Json数组 一眼就能快速上手
- Android 使用GSON解析JSON 并转换为JAVA对象
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- AndroidAsyncHttp与Gson或者Json组合使用,请求直接返回解析对象
- iOS代码技巧之ASIHttpRequest类库的使用及Json解析(以解析中国天气网天气预报为例)
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- Android开发-Volley-解析Json使用方法-2-完整Demo-AndroidStudio
- Android开发-Volley-解析Json使用方法-3-完整Demo-AndroidStudio
- 百度天气api开发 全解析xml和json格式 使用json-lib jsonObject、 Gson 方式把json 转换成 java对象
- kotlin简单小demo,请求,解析,gson的使用,volley的单例
- Android开发-Volley-解析Json使用方法-4-完整Demo-AndroidStudio
- Android开发-Volley-解析Json使用方法-2-完整Demo-AndroidStudio
- Android开发-Volley-解析Json使用方法-完整Demo-AndroidStudio
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段