[Android | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用
来源:互联网 发布:淘宝买家版下载 编辑:程序博客网 时间:2024/06/05 11:48
2016年9月22日 课上小练习,使用spinner选择地区。加载Assets/citycode.json中地区所对应代码。然后根据Api在线加载天气信息。很简单,重点在于Json对象与数组混合,分层解析就好。以及Volley框架的使用。
新增了源代码下载。
本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); } }}
LruBitmapCache
volley图片加载类,如果不需要可以在上面注释掉 ↓
/** * 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 | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用
- kotlin简单小demo,请求,解析,gson的使用,volley的单例
- 使用Gson解析json 数组转对象
- android中json解析的两个工具:Gson和Jackson的使用小demo
- Gson解析json对象,json数组
- Android使用gson解析json
- Android 使用GSON解析JSON 并转换为JAVA对象
- 使用Gson转化天气预报Json
- Gson解析小技巧——解析数组json字符串——一行代码搞定
- android开发之 Gson 解析json数组
- Android天气预报 简单Demo
- Gson解析json数组
- Gson解析json数组
- gson解析json数组
- Gson解析json数组
- Gson解析Json数组
- gson解析json数组
- Android JSON数据格式的解析,与简单对象、带泛型的List和Map的转换,以及GSON的使用
- 主题
- 第四周 项目3.3 单链表应用之判断是否递增
- day15 python a 和span标签
- 平日小问题(4):C++的随机数函数
- 进程间通信--无名管道
- [Android | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用
- DOM
- 谈谈深度学习中的 Batch_Size
- JPush的使用简单范例
- kali linux nc基本教程
- UVa227 谜题 Puzzle
- 希尔排序
- opencv 学习笔记第一天
- android 导入第三方包出错