使用 GSON 解析 JSON 以在 Android 中填充 ListView
Using GSON to parse JSON to Populate a ListView in Android
大家好,我尝试了很多,在这里找到了很多帖子,但无法解决问题..
金迪帮助我.!
Json 看起来像这样:
[
{
"IDNumber": 2,
"Name": "PDP",
"FatherName": "DER",
"Age": "AA",
"DateOfBirth": "16th Nov YYYY",
"Occupation": "Senior .NET Dev",
"MartialStatus": "UnMarried",
"Brand": "YYZ",
"UserStatus": "Family"
},
{
"IDNumber": 3,
"Name": "EWR",
"FatherName": "GRT",
"Age": "AA",
"DateOfBirth": "16th May YYYY",
"Occupation": "Executive Shu Shef",
"MartialStatus": "Married",
"Brand": "XXX",
"UserStatus": "Family"
},
{
"IDNumber": 4,
"Name": "TR",
"FatherName": "FR",
"Age": "AA",
"DateOfBirth": "29th Nov YYYY",
"Occupation": "Senior Consultant",
"MartialStatus": "Married",
"Brand": "XXY",
"UserStatus": "Family"
},
{
"IDNumber": 5,
"Name": "S M DEWW",
"FatherName": "M FRE",
"Age": "21",
"DateOfBirth": "DD MM 1994",
"Occupation": "Student | Tutor",
"MartialStatus": "UnMarried",
"Brand": "NED",
"UserStatus": "Friend"
}
]
现在是 class PersonData
的代码
public class PersonData implements Serializable{
private static final long serialVersionUID = 1L;
@SerializedName("IDNumber")
public String IDNumber;
@SerializedName("Name")
public String Name;
@SerializedName("FatherName")
public String FatherName;
.... for all fields....
@SerializedName("UserStatus")
public String UserStatus;
public PersonData() {
}
}
异步Class
public class Main extends ListActivity {
Button GetData;
ListView listView;
String URL = "http://192.168.0.100:7001/com.faisal.REST_WS/api/v1/json";
List<PersonData> pd = new ArrayList<PersonData>();
MyCustomAdapter dataAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetData = (Button) findViewById(R.id.btn_GET);
GetData.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
APICaller caller = new APICaller();
caller.execute();
}
});
}
class APICaller extends AsyncTask<Object, Object, Object> {
@Override
protected Object doInBackground(Object... params) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(URL);
ResponseHandler<String> handler = new BasicResponseHandler();
Object result = new Object();
try {
result = client.execute(request, handler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void onPostExecute(Object result) {
String json = result.toString();
Gson gson = new Gson();
Type type = new TypeToken<PersonData>() {
}.getType();
List<PersonData> pd = (List<PersonData>) gson
.fromJson(json, type);
dataAdapter = new MyCustomAdapter(getApplicationContext(), pd);
listView.setAdapter(dataAdapter);
}
}
现在是自定义适配器
public class MyCustomAdapter extends ArrayAdapter<PersonData> {
private final List<PersonData> list;
private final Context context;
// private final int viewid;
public MyCustomAdapter(Context context, List<PersonData> list) {
super(context, R.layout.rowlayout, list);
this.context = context;
this.list = list;
// this.viewid = R.layout.rowlayout;
}
class ViewHolder {
protected TextView idnumber;
protected TextView name;
protected TextView fathername;
protected TextView occupation;
protected TextView age;
protected TextView ms;
protected TextView us;
protected TextView dob;
protected TextView brand;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
LayoutInflater inflator = ((Activity) context).getLayoutInflater();
view = inflator.inflate(R.layout.rowlayout, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.idnumber = (TextView) view.findViewById(R.id.idn);
viewHolder.name = (TextView) view.findViewById(R.id.name);
viewHolder.fathername = (TextView) view.findViewById(R.id.fn);
viewHolder.occupation = (TextView) view.findViewById(R.id.Occup);
viewHolder.age = (TextView) view.findViewById(R.id.age);
viewHolder.dob = (TextView) view.findViewById(R.id.DofB);
viewHolder.ms = (TextView) view.findViewById(R.id.M_S);
viewHolder.us = (TextView) view.findViewById(R.id.U_S);
viewHolder.brand = (TextView) view.findViewById(R.id.brand);
view.setTag(viewHolder);
ViewHolder holder = (ViewHolder) view.getTag();
holder.idnumber.setText(list.get(position).IDNumber);
holder.name.setText(list.get(position).Name);
holder.fathername.setText(list.get(position).FatherName);
holder.occupation.setText(list.get(position).Occupation);
holder.age.setText(list.get(position).Age);
holder.ms.setText(list.get(position).MartialStatus);
holder.us.setText(list.get(position).UserStatus);
holder.brand.setText(list.get(position).Brand);
holder.dob.setText(list.get(position).DateOfBirth);
return view;
}
}
它给出错误
01-16 13:21:43.708: E/AndroidRuntime(1594): FATAL EXCEPTION: main
01-16 13:21:43.708: E/AndroidRuntime(1594): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was STRING at line 1 column 1
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory
$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.faisal.api_1_gson.Main$APICaller.onPostExecute(Main.java:86)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access0(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read
(ReflectiveTypeAdapterFactory.java:165)
... 15 more
请帮助我,自从过去两天以来我一直坚持下去,请原谅我这里有关于这个主题的问题,但正如我所说我无法让它工作..
第一点是 class APICaller
IDNumder 字段似乎是 String 类型。但是在JSON中IDNumder显然不是String,而是一个整数值。
我认为问题在于您用来解析字符串的 class 应该具有完全相同的结构。您的 JSON 字符串是一个人物对象列表。所以,你应该使用的 class 看起来应该是这样的:
public class Persons {
List<PersonData> persons;
}
然后在 onPostExecute 中:
List<PersonData> pd = gson.fromJson(json, Persons.class);
并且肯定存在 ID 号为整数的错误,因此您应该更改 PersonData class 中的数据类型,如@Fran
所述
编辑 1:
上述方法的问题在于,如果您的 JSON 数组被包装在一个对象中,这会起作用。
类似于:
{
"persons":[
{
"IDNumber":2,
"Name":"Saqib",
"FatherName":"Sami",
"Age":"AA",
"DateOfBirth":"16th Nov YYYY",
"Occupation":"Senior .NET Dev",
"MartialStatus":"UnMarried",
"Brand":"YYZ",
"UserStatus":"Family"
}
]
...
...
}
但是您的数据没有包装在对象中,所以这里是您可以直接解析的方法 JSON Array.Your 方法几乎是正确的,但是您使用了错误的类型标记。
String jsonString = "[\r\n {\r\n \"IDNumber\": 2,\r\n \"Name\": \"Saqib\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"16th Nov YYYY\",\r\n \"Occupation\": \"Senior .NET Dev\",\r\n \"MartialStatus\": \"UnMarried\",\r\n \"Brand\": \"YYZ\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 3,\r\n \"Name\": \"Asim\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"16th May YYYY\",\r\n \"Occupation\": \"Executive Shu Shef\",\r\n \"MartialStatus\": \"Married\",\r\n \"Brand\": \"XXX\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 4,\r\n \"Name\": \"Wali\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"29th Nov YYYY\",\r\n \"Occupation\": \"Senior Consultant\",\r\n \"MartialStatus\": \"Married\",\r\n \"Brand\": \"XXY\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 5,\r\n \"Name\": \"S M Sami Uddin\",\r\n \"FatherName\": \"M Uddin\",\r\n \"Age\": \"21\",\r\n \"DateOfBirth\": \"DD MM 1994\",\r\n \"Occupation\": \"Student | Tutor\",\r\n \"MartialStatus\": \"UnMarried\",\r\n \"Brand\": \"NED\",\r\n \"UserStatus\": \"Friend\"\r\n }\r\n]";
Gson gson = new Gson();
Type listType = new TypeToken<List<PersonData>>() {}.getType();
List<PersonData> persons = (List<PersonData>) gson.fromJson(jsonString,
listType);
System.out.println(persons.size());
尝试像这样解析它:
List<PersonData> pd = gson
.fromJson(json, new TypeToken<List<PersonData>>(){}.getType());
也尝试将结果对象作为 JSONObject,如下所示:
JSONObject result;
HttpResponse response = httpclient.execute(httppost);
String temp = EntityUtils.toString(response.getEntity());
if (temp == null || temp.trim().equals("")) {
} else {
result = new JSONObject(temp);
}
大家好,我尝试了很多,在这里找到了很多帖子,但无法解决问题.. 金迪帮助我.!
Json 看起来像这样:
[
{
"IDNumber": 2,
"Name": "PDP",
"FatherName": "DER",
"Age": "AA",
"DateOfBirth": "16th Nov YYYY",
"Occupation": "Senior .NET Dev",
"MartialStatus": "UnMarried",
"Brand": "YYZ",
"UserStatus": "Family"
},
{
"IDNumber": 3,
"Name": "EWR",
"FatherName": "GRT",
"Age": "AA",
"DateOfBirth": "16th May YYYY",
"Occupation": "Executive Shu Shef",
"MartialStatus": "Married",
"Brand": "XXX",
"UserStatus": "Family"
},
{
"IDNumber": 4,
"Name": "TR",
"FatherName": "FR",
"Age": "AA",
"DateOfBirth": "29th Nov YYYY",
"Occupation": "Senior Consultant",
"MartialStatus": "Married",
"Brand": "XXY",
"UserStatus": "Family"
},
{
"IDNumber": 5,
"Name": "S M DEWW",
"FatherName": "M FRE",
"Age": "21",
"DateOfBirth": "DD MM 1994",
"Occupation": "Student | Tutor",
"MartialStatus": "UnMarried",
"Brand": "NED",
"UserStatus": "Friend"
}
]
现在是 class PersonData
的代码public class PersonData implements Serializable{
private static final long serialVersionUID = 1L;
@SerializedName("IDNumber")
public String IDNumber;
@SerializedName("Name")
public String Name;
@SerializedName("FatherName")
public String FatherName;
.... for all fields....
@SerializedName("UserStatus")
public String UserStatus;
public PersonData() {
}
}
异步Class
public class Main extends ListActivity {
Button GetData;
ListView listView;
String URL = "http://192.168.0.100:7001/com.faisal.REST_WS/api/v1/json";
List<PersonData> pd = new ArrayList<PersonData>();
MyCustomAdapter dataAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetData = (Button) findViewById(R.id.btn_GET);
GetData.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
APICaller caller = new APICaller();
caller.execute();
}
});
}
class APICaller extends AsyncTask<Object, Object, Object> {
@Override
protected Object doInBackground(Object... params) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(URL);
ResponseHandler<String> handler = new BasicResponseHandler();
Object result = new Object();
try {
result = client.execute(request, handler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void onPostExecute(Object result) {
String json = result.toString();
Gson gson = new Gson();
Type type = new TypeToken<PersonData>() {
}.getType();
List<PersonData> pd = (List<PersonData>) gson
.fromJson(json, type);
dataAdapter = new MyCustomAdapter(getApplicationContext(), pd);
listView.setAdapter(dataAdapter);
}
}
现在是自定义适配器
public class MyCustomAdapter extends ArrayAdapter<PersonData> {
private final List<PersonData> list;
private final Context context;
// private final int viewid;
public MyCustomAdapter(Context context, List<PersonData> list) {
super(context, R.layout.rowlayout, list);
this.context = context;
this.list = list;
// this.viewid = R.layout.rowlayout;
}
class ViewHolder {
protected TextView idnumber;
protected TextView name;
protected TextView fathername;
protected TextView occupation;
protected TextView age;
protected TextView ms;
protected TextView us;
protected TextView dob;
protected TextView brand;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
LayoutInflater inflator = ((Activity) context).getLayoutInflater();
view = inflator.inflate(R.layout.rowlayout, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.idnumber = (TextView) view.findViewById(R.id.idn);
viewHolder.name = (TextView) view.findViewById(R.id.name);
viewHolder.fathername = (TextView) view.findViewById(R.id.fn);
viewHolder.occupation = (TextView) view.findViewById(R.id.Occup);
viewHolder.age = (TextView) view.findViewById(R.id.age);
viewHolder.dob = (TextView) view.findViewById(R.id.DofB);
viewHolder.ms = (TextView) view.findViewById(R.id.M_S);
viewHolder.us = (TextView) view.findViewById(R.id.U_S);
viewHolder.brand = (TextView) view.findViewById(R.id.brand);
view.setTag(viewHolder);
ViewHolder holder = (ViewHolder) view.getTag();
holder.idnumber.setText(list.get(position).IDNumber);
holder.name.setText(list.get(position).Name);
holder.fathername.setText(list.get(position).FatherName);
holder.occupation.setText(list.get(position).Occupation);
holder.age.setText(list.get(position).Age);
holder.ms.setText(list.get(position).MartialStatus);
holder.us.setText(list.get(position).UserStatus);
holder.brand.setText(list.get(position).Brand);
holder.dob.setText(list.get(position).DateOfBirth);
return view;
}
}
它给出错误
01-16 13:21:43.708: E/AndroidRuntime(1594): FATAL EXCEPTION: main
01-16 13:21:43.708: E/AndroidRuntime(1594): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was STRING at line 1 column 1
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory
$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.faisal.api_1_gson.Main$APICaller.onPostExecute(Main.java:86)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access0(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read
(ReflectiveTypeAdapterFactory.java:165)
... 15 more
请帮助我,自从过去两天以来我一直坚持下去,请原谅我这里有关于这个主题的问题,但正如我所说我无法让它工作..
第一点是 class APICaller
IDNumder 字段似乎是 String 类型。但是在JSON中IDNumder显然不是String,而是一个整数值。
我认为问题在于您用来解析字符串的 class 应该具有完全相同的结构。您的 JSON 字符串是一个人物对象列表。所以,你应该使用的 class 看起来应该是这样的:
public class Persons {
List<PersonData> persons;
}
然后在 onPostExecute 中:
List<PersonData> pd = gson.fromJson(json, Persons.class);
并且肯定存在 ID 号为整数的错误,因此您应该更改 PersonData class 中的数据类型,如@Fran
所述编辑 1:
上述方法的问题在于,如果您的 JSON 数组被包装在一个对象中,这会起作用。
类似于:
{
"persons":[
{
"IDNumber":2,
"Name":"Saqib",
"FatherName":"Sami",
"Age":"AA",
"DateOfBirth":"16th Nov YYYY",
"Occupation":"Senior .NET Dev",
"MartialStatus":"UnMarried",
"Brand":"YYZ",
"UserStatus":"Family"
}
]
...
...
}
但是您的数据没有包装在对象中,所以这里是您可以直接解析的方法 JSON Array.Your 方法几乎是正确的,但是您使用了错误的类型标记。
String jsonString = "[\r\n {\r\n \"IDNumber\": 2,\r\n \"Name\": \"Saqib\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"16th Nov YYYY\",\r\n \"Occupation\": \"Senior .NET Dev\",\r\n \"MartialStatus\": \"UnMarried\",\r\n \"Brand\": \"YYZ\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 3,\r\n \"Name\": \"Asim\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"16th May YYYY\",\r\n \"Occupation\": \"Executive Shu Shef\",\r\n \"MartialStatus\": \"Married\",\r\n \"Brand\": \"XXX\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 4,\r\n \"Name\": \"Wali\",\r\n \"FatherName\": \"Sami\",\r\n \"Age\": \"AA\",\r\n \"DateOfBirth\": \"29th Nov YYYY\",\r\n \"Occupation\": \"Senior Consultant\",\r\n \"MartialStatus\": \"Married\",\r\n \"Brand\": \"XXY\",\r\n \"UserStatus\": \"Family\"\r\n },\r\n {\r\n \"IDNumber\": 5,\r\n \"Name\": \"S M Sami Uddin\",\r\n \"FatherName\": \"M Uddin\",\r\n \"Age\": \"21\",\r\n \"DateOfBirth\": \"DD MM 1994\",\r\n \"Occupation\": \"Student | Tutor\",\r\n \"MartialStatus\": \"UnMarried\",\r\n \"Brand\": \"NED\",\r\n \"UserStatus\": \"Friend\"\r\n }\r\n]";
Gson gson = new Gson();
Type listType = new TypeToken<List<PersonData>>() {}.getType();
List<PersonData> persons = (List<PersonData>) gson.fromJson(jsonString,
listType);
System.out.println(persons.size());
尝试像这样解析它:
List<PersonData> pd = gson
.fromJson(json, new TypeToken<List<PersonData>>(){}.getType());
也尝试将结果对象作为 JSONObject,如下所示:
JSONObject result;
HttpResponse response = httpclient.execute(httppost);
String temp = EntityUtils.toString(response.getEntity());
if (temp == null || temp.trim().equals("")) {
} else {
result = new JSONObject(temp);
}