mfaisalhyder
mfaisalhyder

Reputation: 2284

Using GSON to parse JSON to Populate a ListView in Android

Hye all , i tried a lot and found many posts here but couldn't solve the problem.. Kinldy help me .!

Json looks like this:

[
 {
  "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"
 }
]

Now the code for 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() {
 }

}

Async 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);

    }
}

Now the Custom Adapter

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;
    }
}

It gives Error

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.access$600(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

Kindly help here i am stuck on it since last two days , pardon me there are questions here on this topic but as i said i could not get it work..

Upvotes: 1

Views: 2960

Answers (3)

Shivam Verma
Shivam Verma

Reputation: 8023

I think the problem is that the class you're using to parse the String should have the exact same structure. Your JSON String is a List of Person Objects. So, the class that you should be using should look something like this :

public class Persons {
    List<PersonData> persons;
}

and then in onPostExecute :

List<PersonData> pd = gson.fromJson(json, Persons.class);

And there's definitely the bug where the Id number is an integer so you should change the datatype in the PersonData class as mentioned by @Fran

Edit 1 :

The problem with the above approach was that this would've worked if your JSON Array was wrapped in an Object.

Something like :

{  
   "persons":[  
      {  
         "IDNumber":2,
         "Name":"Saqib",
         "FatherName":"Sami",
         "Age":"AA",
         "DateOfBirth":"16th Nov YYYY",
         "Occupation":"Senior .NET Dev",
         "MartialStatus":"UnMarried",
         "Brand":"YYZ",
         "UserStatus":"Family"
      }
   ]
...
...
}

But your data isn't wrapped in an object, so here is how you can directly parse a JSON Array.Your approach was almost correct but you were using the wrong type token.

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());

Upvotes: 2

AndiM
AndiM

Reputation: 2188

Try to parse it like :

List<PersonData> pd = gson
                .fromJson(json, new TypeToken<List<PersonData>>(){}.getType());

Also try result object as a JSONObject like this :

JSONObject result;
HttpResponse response = httpclient.execute(httppost);
        String  temp = EntityUtils.toString(response.getEntity());

            if (temp == null || temp.trim().equals("")) {

            } else {
                result = new JSONObject(temp);
            }

Upvotes: 0

FrAn
FrAn

Reputation: 434

Well first point is in the class APICaller the IDNumder field seems to be type String. But in the JSON IDNumder is clearly not String, but an integer value.

Upvotes: 0

Related Questions