您的位置:首页 > 移动开发 > Android开发

[Android | 小代码] 天气预报 简易Demo json解析数组+对象 Gson+Volley简单使用

2016-09-22 20:39 986 查看
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 json gson
相关文章推荐