最近做的项目是一个打车类的项目,需要选择地址,而数据是Json数据。因为这些数据不对公司造成任何的损失,也没有涉及到任何的隐私或者商业秘密,所以就写此文,说说暂时的解决方法吧,嘻嘻!
遇到的问题:不是标准的json数据,有些甚至没有key。比如说一开始的北京,0,这些都没有key。另外,有key的都是数字。是数据的话,第一个层级是0~33.然而第二个层级是不定的,也就是不能用for循环啦,哈哈!
先看看数据吧:
全国省市县三级Json数据
package com.sunofbeaches.jsondemo;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
parserJson();
}
private void parserJson() {
// 获取到数据
String jsonString = getResources().getString(R.string.jsonstring);
// json解析者
JsonParser jsonParser = new JsonParser();
// 解析成Json对象
JsonObject asJsonObject = jsonParser.parse(jsonString)
.getAsJsonObject();
// 遍历里头的数据
Set> entrySet = asJsonObject.entrySet();
for (Entry entry : entrySet) {
JsonArray asJsonArray = entry.getValue().getAsJsonArray();
String asString = asJsonArray.get(0).getAsString();// 省份
System.out.println("asString--" + asString);
int asInt = asJsonArray.get(1).getAsInt();// 那个数字
System.out.println("asInt--" + asInt);
// 获取到第3个,又是一个json对象
JsonObject asJsonObject2 = asJsonArray.get(2).getAsJsonObject();
// 遍历第2级数据
Set> entrySet2 = asJsonObject2
.entrySet();
for (Entry entry2 : entrySet2) {
JsonArray asJsonArray2 = entry2.getValue().getAsJsonArray();
if (asJsonArray2.size() == 1) {// 这一个判断是因为在河北市(42249)里头只有一级,没有下一级了
String asString2 = asJsonArray2.get(0).getAsString();// 市级
System.out.println("asString2====" + asString2);
} else {
String asString2 = asJsonArray2.get(0).getAsString();// 市级
System.out.println("asString2====" + asString2);
int asInt2 = asJsonArray2.get(1).getAsInt();// 数字
System.out.println("asInt=====" + asInt2);
// 获取第三级数据(县级/区)
JsonObject asJsonObject3 = asJsonArray2.get(2)
.getAsJsonObject();
// 遍历第三级数据
Set> entrySet3 = asJsonObject3
.entrySet();
for (Entry entry3 : entrySet3) {
JsonArray asJsonArray3 = entry3.getValue()
.getAsJsonArray();
String asString3 = asJsonArray3.get(0).getAsString();// 县级数据
System.out.println("asString3>>>>>>" + asString3);
}
}
}
}
}
}
因为数据不标准,所以我们不能直接创建一个bean类,用gson直接解析,因为gson的直接解析是使用反射的方法來做的。那么这里也说说吧,如果直接是用bean类來解析的话,需要它的权限所有都是public的,类是public的,里面的成员,所有都是public的,这是第一点。那么第二点就是这个里面的名字要和这个json数据里的名字要一样哦。就是对应的数据名字要一样,原因还是因为使用反射的方法來解析嘛。
ok,那么通过上面这个核心方法,我们可以定义出以下的bean类,然后手动地赋值,就可以封装起來了。
这些bean 结构和Json里的数据是一样的结构,只是名字不一样。因为Java中数字不能作为变量的名字嘛,是吧!这个我们小时候学java就知道啦,标识符的规则。
好的,直接上bean类吧!
这个是整体的bean类
package com.sunofbeaches.jsondemo.bean;
import java.util.List;
public class JsonBean {
public List Provinces;
}
这个省份的bean类
package com.sunofbeaches.jsondemo.bean;
import java.util.List;
public class Provinces {
public String provinceName;
public int shengNumber;
public List cities;
}
市级的bean类
package com.sunofbeaches.jsondemo.bean;
import java.util.List;
public class City {
public String cityName;
public int chengshiNumber;
public List countries;
}
镇/区级的bean类
package com.sunofbeaches.jsondemo.bean;
public class Country {
public String countryNmae;
}
有了bean类之后,我们可以对数据进行封装,因为前面我们已经解析了数据嘛!
数据封装核心类,其实和这个解析类在一起了,那么个类的功能就是解析数据,并封装数据,返回一个bean类
package com.sunofbeaches.jsondemo;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Set;
import android.content.Context;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.orange.jsondemo.R;
import com.sunofbeaches.jsondemo.bean.City;
import com.sunofbeaches.jsondemo.bean.Country;
import com.sunofbeaches.jsondemo.bean.JsonBean;
import com.sunofbeaches.jsondemo.bean.Provinces;
public class GetAllDatasBean {
public JsonBean getAllDatas(Context context) {
// 整体Bean类
JsonBean bean = new JsonBean();
bean.Provinces = new ArrayList();
// 获取到数据
String jsonString = context.getResources().getString(
R.string.jsonstring);
// json解析者
JsonParser jsonParser = new JsonParser();
// 解析成Json对象
JsonObject asJsonObject = jsonParser.parse(jsonString)
.getAsJsonObject();
// 遍历里头的数据
Set> entrySet = asJsonObject.entrySet();
for (Entry entry : entrySet) {
// 省bean类
Provinces province = new Provinces();
province.cities = new ArrayList();
JsonArray asJsonArray = entry.getValue().getAsJsonArray();
String asString = asJsonArray.get(0).getAsString();// 省份
// 赋值
province.provinceName = asString;
System.out.println("asString>>" + asString);
int asInt = asJsonArray.get(1).getAsInt();// 那个数字
// 赋值
province.shengNumber = asInt;
// 获取到第3个,又是一个json对象
JsonObject asJsonObject2 = asJsonArray.get(2).getAsJsonObject();
// 遍历第2级数据
Set> entrySet2 = asJsonObject2
.entrySet();
for (Entry entry2 : entrySet2) {
JsonArray asJsonArray2 = entry2.getValue().getAsJsonArray();
// 市bean类
City city = new City();
city.countries = new ArrayList();
if (asJsonArray2.size() == 1) {// 这一个判断是因为在河北市(42249)里头只有一级,没有下一级了
String asString2 = asJsonArray2.get(0).getAsString();// 市级
city.cityName = asString2;
city.chengshiNumber = -1;// 表示没有
city.countries = null;// 表示没有,使用的时候要记得判断
} else {
String asString2 = asJsonArray2.get(0).getAsString();// 市级
// 赋值
city.cityName = asString2;
int asInt2 = asJsonArray2.get(1).getAsInt();// 数字
// 赋值
city.chengshiNumber = asInt2;
// 获取第三级数据(县级/区)
JsonObject asJsonObject3 = asJsonArray2.get(2)
.getAsJsonObject();
// 遍历第三级数据
Set> entrySet3 = asJsonObject3
.entrySet();
for (Entry entry3 : entrySet3) {
JsonArray asJsonArray3 = entry3.getValue()
.getAsJsonArray();
String asString3 = asJsonArray3.get(0).getAsString();// 县级数据
// 县级/区数据bean类
Country country = new Country();
country.countryNmae = asString3;
city.countries.add(country);// 添加县/区
}
}
province.cities.add(city);
}
bean.Provinces.add(province);
}
return bean;
}
}
到这里,数据已经完成了解析,也完成了封装,可以直接得到一个包含了所有数据的类。那么怎么使用呢?下面,就通过一个例子來使用一下这面里的数据吧!
当然,是没有数据的,嘻嘻!
package com.sunofbeaches.jsondemo;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Spinner;
import android.widget.TextView;
import com.orange.jsondemo.R;
import com.sunofbeaches.jsondemo.adapter.MyBaseAdapter;
import com.sunofbeaches.jsondemo.bean.City;
import com.sunofbeaches.jsondemo.bean.Country;
import com.sunofbeaches.jsondemo.bean.JsonBean;
import com.sunofbeaches.jsondemo.bean.Provinces;
public class MainActivity extends Activity {
private Spinner mProvinces;
private Spinner mCities;
private Spinner mCountries;
private JsonBean mDatas;
private List mProDatas;
private List mCitDatas;
private List mCounDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initDatas();
initEvent();
}
private void initView() {
setContentView(R.layout.activity_main);
mProvinces = (Spinner) this.findViewById(R.id.provinces);
mCities = (Spinner) this.findViewById(R.id.cities);
mCountries = (Spinner) this.findViewById(R.id.countries);
}
private void initDatas() {
mDatas = new GetAllDatasBean().getAllDatas(this);
mProDatas = mDatas.Provinces;
Log.d("message", mProDatas.size() + ">>>>");
mProvinces.setAdapter(new ProvincesAdapter(mProDatas));
}
private class ProvincesAdapter extends MyBaseAdapter {
public ProvincesAdapter(List datas) {
super(datas);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MainActivity.this);
tv.setText(mProDatas.get(position).provinceName);
return tv;
}
}
/**
* 第二级数据目录
*/
private void initSecondDatas(int position) {
mCitDatas = mProDatas.get(position).cities;
// 设置适配器
mCities.setAdapter(new CitiesAdapter(mCitDatas));
}
private class CitiesAdapter extends MyBaseAdapter {
public CitiesAdapter(List datas) {
super(datas);
}
// 复写方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MainActivity.this);
tv.setText(mCitDatas.get(position).cityName);
return tv;
}
}
private void initCountrieDatas(int position) {
// 获取数据
mCounDatas = mCitDatas.get(position).countries;
// 设置适配器
mCountries.setAdapter(new CountriesAdapter(mCounDatas));
}
private class CountriesAdapter extends MyBaseAdapter {
public CountriesAdapter(List datas) {
super(datas);
}
// 复写一个方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MainActivity.this);
tv.setText(mCounDatas.get(position).countryNmae);
return tv;
}
}
private void initEvent() {
// 省级数据监听
mProvinces.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view,
int position, long id) {
initSecondDatas(position);
}
@Override
public void onNothingSelected(AdapterView> parent) {
}
});
// 市级数据监听
mCities.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view,
int position, long id) {
// 去设定县级/区的数据
initCountrieDatas(position);
}
@Override
public void onNothingSelected(AdapterView> parent) {
}
});
}
}
package com.sunofbeaches.jsondemo.adapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class MyBaseAdapter extends BaseAdapter {
private List mDatas;
// 通过构造函数來获取到数据
public MyBaseAdapter(List datas) {
this.mDatas = datas;
}
@Override
public int getCount() {
if (mDatas != null) {
return mDatas.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if (mDatas != null) {
return mDatas.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
if (mDatas != null) {
return position;
}
return 0;
}
// 这个方法由子类复写
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
到了这里,相信你已经明白了怎么搞这些数据。数据解析了,类也封装了,数据也使用了,哈哈!如果有什么疑问欢迎到我们的社区讨论哦!
阳光沙滩
或许,你可以分享呢!谢谢哦!
这样吧,最后还是发一个动图看看吧!