使用 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 &#x7c; 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);
            }