Android SharedPreferences Tutorial and Example

Parsing JSON Data with Gson in Android

Modern Android apps frequently receive JSON from REST APIs, cloud services and local files. Gson is a Java library that converts JSON into Kotlin or Java objects, making network responses easier to read, validate and display in an Android interface.

For an app used in Australia, this might mean loading public transport updates in Melbourne, café listings around Brisbane or delivery information for a customer in Perth. A reliable parser helps your app deal with changing response formats while keeping the code understandable for beginners and maintainable for experienced developers.

What Gson Does in Android

JSON represents information with objects, arrays, strings, numbers, Boolean values and nulls. A response might contain a product name, an Australian dollar price and a list of suburbs. Reading every field manually with JSONObject can become repetitive, particularly when the response includes nested objects.

Gson maps matching JSON property names to fields in a model class. It can also serialise an Android object into JSON when an app needs to save data or send a request. This approach separates data parsing from activities and fragments, which makes an application easier to test.

A simple JSON response could look like this:

{
  "id": 17,
  "name": "Reusable Water Bottle",
  "price": 24.95,
  "available": true
}

The matching Java model is concise:

public class Product {
    private int id;
    private String name;
    private double price;
    private boolean available;

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

Adding Gson To An Android Project

For a Gradle-based Android project, add the Gson dependency to the module-level build.gradle file. Check the current version in the official Maven repository or your project’s dependency catalogue rather than copying an outdated version.

dependencies {
    implementation 'com.google.code.gson:gson:2.11.0'
}

After synchronising Gradle, create a Gson instance and parse a JSON string:

Gson gson = new Gson();

String json = "{\"id\":17,\"name\":\"Reusable Water Bottle\","
        + "\"price\":24.95,\"available\":true}";

Product product = gson.fromJson(json, Product.class);

The fromJson method creates a Product object from the supplied text. In a real Android application, the JSON will usually come from Retrofit, an HTTP client or a file rather than a hard-coded string. Network work should run away from the main thread so the interface remains responsive on mobile connections.

Matching JSON With Model Classes

Gson uses field names by default. If the API returns first_name, while your Java field uses firstName, apply @SerializedName to connect the two names:

public class Customer {
    @SerializedName("first_name")
    private String firstName;

    private String suburb;
}

This is useful when working with established APIs that follow snake_case naming. It also keeps your Android code consistent with normal Java naming conventions. Import the annotation with com.google.gson.annotations.SerializedName.

Nested JSON can be represented with nested model classes. An order containing a customer and several items might use Customer, OrderItem and Order classes. For arrays, use a list:

Type listType = new TypeToken<List<Product>>() {}.getType();
List<Product> products = gson.fromJson(jsonArray, listType);

TypeToken preserves the generic type information that Java normally removes at runtime. Without it, Gson may return a collection that is difficult to use safely.

Parsing Responses From An API

When Gson is combined with Retrofit, the library can convert a successful JSON response directly into a model object. A service method could return Call<List<Product>>, allowing Retrofit and Gson to handle the response conversion.

public interface ProductApi {
    @GET("products")
    Call<List<Product>> getProducts();
}

The callback should handle both success and failure:

api.getProducts().enqueue(new Callback<List<Product>>() {
    @Override
    public void onResponse(Call<List<Product>> call,
                           Response<List<Product>> response) {
        if (response.isSuccessful() && response.body() != null) {
            List<Product> products = response.body();
            // Update the adapter here
        }
    }

    @Override
    public void onFailure(Call<List<Product>> call, Throwable error) {
        // Show an error state
    }
});

An Australian retail app may receive prices such as "$24.95" instead of a numeric value. Decide whether the model should store a double, a BigDecimal or the original string. For financial calculations, BigDecimal is safer than floating-point arithmetic, especially when totals are displayed in Australian dollars.

Handling Errors, Nulls And Changing Data

Malformed JSON can throw a JsonSyntaxException, while a missing property may produce a null field. APIs can also change when a business adds a new field or changes a value from a number to text. Validate important values before showing them in a TextView, and give users a useful empty, loading or error state.

try {
    Product product = gson.fromJson(json, Product.class);

    if (product != null && product.getName() != null) {
        nameTextView.setText(product.getName());
    }
} catch (JsonSyntaxException exception) {
    Log.e("ProductParser", "Invalid product JSON", exception);
}

Avoid placing all parsing and error handling in an activity. A repository or ViewModel can request the data, interpret the result and expose a clear state to the UI. This structure is valuable when an app needs to work across Sydney, regional New South Wales and areas with slower or intermittent connectivity.

Use nullable fields for values that the server may omit. For required data, apply validation after parsing rather than assuming that a successful HTTP status guarantees a complete response. Logging should help developers diagnose problems without exposing customer addresses, phone numbers or other private information.

Showing Parsed Data In Android Views

Once Gson has created a list of objects, pass it to a RecyclerView adapter rather than repeatedly parsing the same response inside each row. Format dates, distances and currency values at the presentation layer. For Australian users, use Locale.AU when formatting prices or dates:

NumberFormat currency =
        NumberFormat.getCurrencyInstance(Locale AU);

In valid Java, the locale constant is written with a dot:

NumberFormat currency =
        NumberFormat.getCurrencyInstance(Locale.AU);
priceTextView.setText(currency.format(product.getPrice()));

A long product list, transport timetable or suburb directory may need careful scrolling behaviour. When refining the interface, Android Open Tutorials’ guide to vertical scrollbar styling can help you make scrolling feedback clearer without changing the JSON layer.

Keep the adapter focused on displaying data. If a parsed field needs conversion, such as turning an ISO timestamp into a local date, perform that conversion in a formatter or view-model helper. This prevents business rules from becoming scattered across layout code.

Practical Checks Before Shipping

Test parsing with realistic responses rather than a single ideal example. Include an empty array, missing fields, null values, extra fields and invalid data. A response from a local council, a supermarket service or a transport provider may evolve independently of your Android release cycle.

The following checks provide a useful release routine:

  • Confirm that every important JSON property maps to the intended model field.
  • Test slow responses, HTTP errors and an unavailable network connection.
  • Verify Australian currency, date and time formatting with Locale.AU.
  • Display a useful empty state when a list contains no records.
  • Keep sensitive response data out of logs and crash reports.

Gson is forgiving about unknown fields, which helps when an API adds optional information. It should still be paired with sensible validation, clear user feedback and automated tests. With well-designed models and a separate data layer, JSON parsing remains predictable as the Android project grows.