使用Gson解析json并且加载json中的网络图片

本人刚入行安卓大半年,虽说经验很少,但是我还是想把自己平时做项目过程中的一些东西记录下来,一来大家互相学习,二来自己也能看到自己进步的脚印。


好了,言归正传,这次主要就是一个使用Gson来解析json的例子。先给大家上图:

destoon json格式_destoon json格式

destoon json格式_destoon json格式_02


其实解析json的方法有很多,之前使用JSONObject和JSONArray来解析json也挺不错,可是相比Gson就会显得有些麻烦了。Gson库的下载连接:点击打开链接。我是在本地的tomcat下自己写了一个json,没安装tomcat的请先下载一个tomcat:点击打开链接,下载完毕不需要安装,解压即可使用(需要配置jdk的环境变量),在tomcat的目录webapps\ROOT里面新建一个weather.html页面,json代码如下:


{
    "error": 0,
    "status": "success",
    "date": "2015-03-10",
    "results": [
        {
            "currentCity": "北京",
            "weather_data": [
                {
                    "date": "周一(今天, 实时:19℃)",
                    "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/dayu.png",
                    "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/dayu.png",
                    "weather": "大雨",
                    "wind": "东南风5-6级",
                    "temperature": "18℃"
                },
                {
                    "date": "周二",
                    "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/zhenyu.png",
                    "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
                    "weather": "阵雨转多云",
                    "wind": "西北风4-5级",
                    "temperature": "21 ~ 14℃"
                },
                {
                    "date": "周三",
                    "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/leizhenyu.png",
                    "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/leizhenyu.png",
                    "weather": "雷阵雨",
                    "wind": "西北风4-5级",
                    "temperature": "22 ~ 18℃"
                },
                {
                    "date": "周四",
                    "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/qing.png",
                    "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/qing.png",
                    "weather": "晴",
                    "wind": "东南风2级",
                    "temperature": "28℃"
                }
            ]
        }
    ]
}

然后在tomcat的bin目录下双击打开startup.bat即可开启tomcat服务器,此时打开浏览器,在浏览器地址栏输入:http://192.168.1.14:8080/weather.html,这里你们需要改成你们自己的ip地址,如果页面显示如下则说明服务器端已ok



此时我们需要先写一个javaBean,如果是多层嵌套的话建议写成内部类的形式(注意在javaBean中定义的变量一定要和json中的键保持一致,否则会解析不出来),javaBean代码如下:Status.java

package com.example.gsonparsejson;

import java.util.List;

public class Status {
	private String error;
	private String status;
	private String date;
	private List<results> results;

	public String getError() {
		return error;
	}

	public void setError(String error) {
		this.error = error;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public List<results> getResult() {
		return results;
	}

	public void setResult(List<results> results) {
		this.results = results;
	}
	
	@Override
	public String toString() {
		return "Status [error=" + error + ", status=" + status + ", date="
				+ date + ", result=" + results + "]";
	}


	public class results {
		private String currentCity;
		private List<weather_data> weather_data;

		public String getCurentCity() {
			return currentCity;
		}

		public void setCurentCity(String currentCity) {
			this.currentCity = currentCity;
		}

		public List<weather_data> getWeather_data() {
			return weather_data;
		}

		public void setWeather_data(List<weather_data> weather_data) {
			this.weather_data = weather_data;
		}

		@Override
		public String toString() {
			return "results [curentCity=" + currentCity + ", weather_data="
					+ weather_data + "]";
		}


		public class weather_data {
			private String date;
			private String dayPictureUrl;
			private String nightPictureUrl;
			private String weather;
			private String wind;
			private String temperature;

			public String getDate() {
				return date;
			}

			public void setDate(String date) {
				this.date = date;
			}

			public String getDayPictureUrl() {
				return dayPictureUrl;
			}

			public void setDayPictureUrl(String dayPictureUrl) {
				this.dayPictureUrl = dayPictureUrl;
			}

			public String getNightPictureUrl() {
				return nightPictureUrl;
			}

			public void setNightPictureUrl(String nightPictureUrl) {
				this.nightPictureUrl = nightPictureUrl;
			}

			public String getWeather() {
				return weather;
			}

			public void setWeather(String weather) {
				this.weather = weather;
			}

			public String getWind() {
				return wind;
			}

			public void setWind(String wind) {
				this.wind = wind;
			}

			public String getTemperature() {
				return temperature;
			}

			public void setTemperature(String temperature) {
				this.temperature = temperature;
			}

			@Override
			public String toString() {
				return "weather_data [date=" + date + ", dayPictureUrl="
						+ dayPictureUrl + ", nightPictureUrl="
						+ nightPictureUrl + ", weather=" + weather + ", wind="
						+ wind + ", temperature=" + temperature + "]";
			}
		}
	}
}



接下来就是开始解析了,在activity的oncreate方法中开启一个线程:

new Thread() {
			public void run() {
				 String path = "http://192.168.1.14:8080/weather.html";
				 String jsonString = HttpUtils.getJsonContent(path);// 从网络获取数据
				 Gson gson = new Gson();
				 fromJson = gson.fromJson(jsonString, Status.class);
				 result = fromJson.getResult();
				 weather = fromJson.getResult().get(0).getWeather_data();
				 mHandler.sendEmptyMessage(000);
				};
		}.start();

我是先从网络上获取到数据然后直接用gson.fromjson来解析,这个gson做的还是蛮厉害的。此方法唯一的不好就是需要把json数据从网上copy下来,如果json数据非常大的话,那就要用别的方式获取数据了,推荐可以用Volley 点击打开链接,该博主有详细的介绍,我再贴上我获取数据的工具类:HttpUtils.java

package com.example.gsonparsejson;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

//通过HttpURLCnnection获取链接里的数据,放到流里,然后把流里面的数据转换为字符串
public class HttpUtils {

	public HttpUtils() {
		
	}

	public static String getJsonContent(String url_path) {
		try {
			URL url = new URL(url_path);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(3000);
			connection.setRequestMethod("GET");
			connection.setDoInput(true);
			int code = connection.getResponseCode();
			if (code == 200) {
				return changeInputStream(connection.getInputStream());
			}
		} catch (Exception e) {
			
		}
		return "";
	}

	private static String changeInputStream(InputStream inputStream) {
		// TODO Auto-generated method stub
		String jsonString = "";
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		int len = 0;
		byte[] data = new byte[1024];
		try {
			while ((len = inputStream.read(data)) != -1) {
				outputStream.write(data, 0, len);
			}
			jsonString = new String(outputStream.toByteArray());
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonString;
	}
}

到此为止就已经拿到了json中的数据了,我把他存放在weather这个集合中,之后就是给listview加载adapter设置数据了,我自己写了一个adapter继承自BaseAdapter,里面最重要的方法就是getview了:

@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			weather_data data = weather.get(position);
			View view;
			final ViewHolder holder;
			if (convertView != null) {
				view = convertView;
				holder = (ViewHolder) view.getTag();
			} else {
				view = View.inflate(MainActivity.this, R.layout.weather_item,null);
				holder = new ViewHolder();
				holder.date = (TextView) view.findViewById(R.id.date);
				holder.wea = (TextView) view.findViewById(R.id.wea);
				holder.wind = (TextView) view.findViewById(R.id.wind);
				holder.tem = (TextView) view.findViewById(R.id.tem);
				holder.daypicture = (ImageView) view.findViewById(R.id.daypicture);
				holder.nightpicture = (ImageView) view.findViewById(R.id.nightpicture);
				view.setTag(holder);
			}
			holder.date.setText(data.getDate());
			holder.wea.setText(data.getWeather());
			holder.wind.setText(data.getWind());
			holder.tem.setText(data.getTemperature());
			try {
				URL dayurl = new URL(data.getDayPictureUrl());
				URL nighturl = new URL(data.getNightPictureUrl());
				Utils.onLoadImage(dayurl, new OnLoadImageListener() {  
				    @Override  
				    public void OnLoadImage(Bitmap bitmap, String bitmapPath) {  
				        if(bitmap!=null){  
				        	holder.daypicture.setImageBitmap(bitmap);  
				        }  
				    }  
				});
				Utils.onLoadImage(nighturl, new OnLoadImageListener() {  
				    @Override  
				    public void OnLoadImage(Bitmap bitmap, String bitmapPath) {  
				        if(bitmap!=null){  
				        	holder.nightpicture.setImageBitmap(bitmap);  
				        }  
				    }  
				});
			} catch (Exception e) {
				e.printStackTrace();
			}
			return view;
		}

在该方法里从weather集合里拿到了对应位置的数据然后设置Text就好了,在设置imageview时我是加载了json里面链接的图片,详情可以参考: 点击打开链接,稍后我会把整个项目的连接地址给大家,有兴趣的可以下载来看看,也欢迎大家对我进行指点。最后别忘了在清单文件中添加权限:<uses-permission android:name="android.permission.INTERNET" />



源码下载地址: 点击打开链接