个人觉得对于解析json,首先要把要解析的json结构弄清楚,
先来看一下要解析的结构:
{
"reason": "成功的返回",
"result": {
"stat": "1",
"data": [
{
"title": "排球联赛全明星投票开启 选出你的“男票女票”",
"date": "2017-01-05 10:29",
"category": "体育",
"author_name": "新华网",
"thumbnail_pic_s": "http://03.imgmini.eastday.com/mobile/20170105/20170105102916_561027ce9464e6079701b3fcb84713af_1_mwpm_03200403.jpeg",
"url": "http://mini.eastday.com/mobile/170105102916768.html?qid=juheshuju",
"thumbnail_pic_s03": "http://03.imgmini.eastday.com/mobile/20170105/20170105102916_561027ce9464e6079701b3fcb84713af_1_mwpl_05500201.jpeg"
},
.......
{
"title": "灰暗时期的曙光 利拉德:我会一直把球队扛在肩上",
"date": "2017-01-05 09:52",
"category": "体育",
"author_name": "体坛+",
"thumbnail_pic_s": "http://05.imgmini.eastday.com/mobile/20170105/20170105095209_560edcca65fce11fb785732b39f50f04_1_mwpm_03200403.jpeg",
"url": "http://mini.eastday.com/mobile/170105095209430.html?qid=juheshuju",
"thumbnail_pic_s03": "http://05.imgmini.eastday.com/mobile/20170105/20170105095209_560edcca65fce11fb785732b39f50f04_1_mwpl_05500201.jpeg"
}
]
},
"error_code": 0
}
上面的json结构并不复杂,把结构图画出来看看,如下:
{
reason:
result:{
stat:
data:[
{ .... }
]
}
error_code:
}
看了这个,对于要解析的字符串结构就明白了,最外层有一个字符串和一个整型数:reason和error_code,和一个对象result,
result里面有一个字符串stat和一个数组;数组里面是一个个的对象
明白了这些后解析的思路就明了了;
一,获取这些json:
这些数据是在“聚合数据”上申请的免费接口,顺便说一下这个平台很好用,有很多免费的接口注册就能用,
直接上代码:
//获取网络json数据 public void getJson(){ HttpClient httpClient=new DefaultHttpClient(); HttpGet httpGet=new HttpGet("http://v.juhe.cn/toutiao/index?type=tiyu&key=ad613879997ea92af00c426e087a3a9e"); try{ HttpResponse httpResponse=httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode()==200){ HttpEntity httpEntity=httpResponse.getEntity(); response= EntityUtils.toString(httpEntity,"utf-8");//获取了json,赋给了response } }catch(Exception e){ Toast.makeText(MyNews02.this,"error"+e.toString(),Toast.LENGTH_LONG).show(); } }
二,开始解析:
获取json后,格式化http://www.bejson.com/
在解析之前需要把其中包含的数据格式了解清楚,是对象,是数组还是整型数据;对了 别忘了导包;
我已经加了清晰的注释,看代码
//解析json字符串 public void ParseJson(String json){ try { JSONObject jsonObj = new JSONObject(json); String reason=jsonObj.getString("reason");//获取字符串 int errocode=jsonObj.getInt("error_code"); JSONObject jsonResult=jsonObj.getJSONObject("result");//因为“result”是一个对象,用getJSONObject JSONArray arraydata = jsonResult.getJSONArray("data");//相应地,数组的话用getJSONArray(), if (arraydata != null && arraydata.length() > 0) {//解析之前保证数组非空, for (int i = 0; i < arraydata.length(); i++) {//数组里面包含了很多个对象,获取对象,循环解析 //1)得到i位置的JsonObject JSONObject obj2 = arraydata.getJSONObject(i); //2)开始解析 String title = obj2.getString("title"); String username = obj2.getString("author_name"); String datetime = obj2.getString("date"); String uri = obj2.getString("url"); String img = obj2.getString("thumbnail_pic_s03"); list_title.add(i,title); list_name.add(i,username); list_uri.add(i,uri); list_image.add(i,img); list_date.add(i,datetime);//把需要的字符串放到集合中, } } }catch(Exception e){ Toast.makeText(MyNews02.this,"parse wrong"+e.toString(),Toast.LENGTH_LONG).show(); tv.setText("解析异常:" + e.toString()); } }
三,展示数据,这是一个新闻资讯的api,包含了图片和文字,但是解析出来的是图片链接,要想办法转成图片对象,加一个方法:
//有根据uri获取图片对象 public Bitmap returnBitMap(String url) { URL myFileUrl = null; Bitmap bitmap = null; try { myFileUrl = new URL(url); } catch (MalformedURLException e) { e.printStackTrace(); } try { HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; }
在选择适配器的时候我选的是SimpleAdapter,但是一直报错,后来发现一直报错,百度后才知道:
“SimpleAdapter本身是不支持网络图片的, 如果在Map.put(a,b)中 b为一个Bitmap,程序不会报红色字体,而是在控制台输出绿色的字体,如下05-10 15:46:45.474: I/System.out(846): resolveUri failed on bad bitmap uri:Android.graphics.Bitmap@43e40c08”
尝试了网上给的方法,“使用SimpleAdapter中的方法simpleAdapter.setViewBinder()。”,但是没成功,不知道为什么。后来放弃了SimpleAdapter,用的是自定义的BaseAdapter才显示,
private List<Map<String, Object>> listItems; //商品信息集合 private Context context; //运行上下文 private LayoutInflater listContainer; //视图容器 public final class ListItemView{ //自定义控件集合 public ImageView image; public TextView title; public TextView date; public TextView name; } public MyAdapter(Context context, List<Map<String, Object>> listItems) { this.context = context; listContainer = LayoutInflater.from(context); //创建视图容器并设置上下文 this.listItems = listItems; } public int getCount() { // TODO Auto-generated method stub return listItems.size(); } public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } /** * ListView Item设置 */ public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub Log.e("method", "getView"); final int selectID = position; //自定义视图 ListItemView listItemView = null; if (convertView == null) { listItemView = new ListItemView(); //获取list_item布局文件的视图 convertView = listContainer.inflate(R.layout.layout_listview, null); //获取控件对象 listItemView.image = (ImageView)convertView.findViewById(R.id.imageView); listItemView.title = (TextView)convertView.findViewById(R.id.textView_title); listItemView.date = (TextView)convertView.findViewById(R.id.textView_date); listItemView.name= (TextView)convertView.findViewById(R.id.textView_name); //设置控件集到convertView convertView.setTag(listItemView); }else { listItemView = (ListItemView)convertView.getTag(); } //设置文字和图片 listItemView.image.setImageBitmap((Bitmap) listItems.get(position).get("image")); listItemView.title.setText((String) listItems.get(position).get("title")); listItemView.date.setText((String) listItems.get(position).get("date")); listItemView.name.setText((String)listItems.get(position).get("name")); return convertView; }
来看一下运行效果:
显示出来了,还有需要改进的地方,再接再厉,