Json Parsing using Retrofit

JSON Parsing with Retrofit Library

Retrofit is a REST Client for Android and Java by Square. It makes it relatively easy to retrieve and upload JSON (or other structured data) via a REST-based web service. In Retrofit, you configure which converter is used for the data serialization. Typically for JSON parsing, you use GSon, but you can add custom converters to process XML or other protocols. Retrofit uses the OkHttp library for HTTP requests. Our other tutorial for JSON parsing using Volley

Retrofit Converters

Retrofit can be configured to use a specific converter. This converter handles the data (de)serialization. Several converters are already available for various serialization formats.
  • To convert to and from JSON:
    • Gson: com.squareup.retrofit:converter-gson
    • Jackson: com.squareup.retrofit:converter-jackson
    • Moshi: com.squareup.retrofit:converter-moshi
    • Scalars: com.squareup.retrofit2:converter-scalars
  • To convert to and from Protocol Buffers:
    • Protobuf: com.squareup.retrofit:converter-protobuf
    • Wire: com.squareup.retrofit:converter-wire
  • To convert to and from XML:
    • Simple XML: com.squareup.retrofit:converter-simplexml
Besides the listed converters, you can also create custom converters to process other protocols by subclassing the Converter.Factory class

Creating a New Project

  1. Create a new project in Android Studio from File ⇒ New Project. When it prompts you to select the default activity, select Empty Activity, and proceed or go to Chapter 1 – Getting Started with Android Programming
  2. Open build.gradle and add Retrofit, Scalars, Glide dependencies.
    dependencies {
        ...
        implementation 'com.squareup.retrofit2:retrofit:2.9.0'
        implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
        implementation 'com.github.bumptech.glide:glide:4.11.0'
        annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    }
  3. Make sure to require Internet permissions in your AndroidManifest.xml file:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Start JSON Parsing

  1. Now create a model class named Movie like this.
    public class Movie {
        private String name;
        private String image;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getImage() {
            return image;
        }
    
        public void setImage(String image) {
            this.image = image;
        }
    }
  2. To issue network requests to a REST API with Retrofit, we need to create an instance using the Retrofit.Builder class and configure it with a base URL.
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ApiService.BASE_URL)
            .addConverterFactory(ScalarsConverterFactory.create())
            .build();
  3. The endpoints are defined inside of an interface using special retrofit annotations to encode details about the parameters and request method. Create an interface named ApiService
    public interface ApiService {
        ....
    
        @GET("demo/json-sample.php")
        Call<String> getMovies();
    }
  4. Create custom adapter for binding data with RecycleView class named MovieAdapter.java

    public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyHolder> {
        private Context mContext;
        private List<Movie> movieList;
    
        public MovieAdapter(Context mContext, List<Movie> movieList) {
            this.mContext = mContext;
            this.movieList = movieList;
        }
    
        @NonNull
        @Override
        public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_items, parent, false);
            return new MyHolder(view);
        }
    
        @Override
        public void onBindViewHolder(@NonNull MyHolder holder, int position) {
            Movie item = movieList.get(position);
    
            holder.tvTitle.setText(item.getName());
    
            GlideApp.with(mContext)
                    .load(item.getImage())
                    .into(holder.ivThumb);
        }
    
        @Override
        public int getItemCount() {
            return movieList.size();
        }
    
        static class MyHolder extends RecyclerView.ViewHolder {
            MaterialTextView tvTitle;
            AppCompatImageView ivThumb;
    
            public MyHolder(@NonNull View itemView) {
                super(itemView);
    
                tvTitle = itemView.findViewById(R.id.tv_title);
                ivThumb = itemView.findViewById(R.id.iv_thumb);
            }
        }
    }
  5. Inside the onCreate() method of the MainActivity.java, we initialize an instance of the ApiService interface, the RecyclerView, and also the adapter. Finally, we call the loadData() method.
    private void loadData() {
        if (Functions.isNetworkConnected(this)) {
            mProgressBar.setVisibility(View.VISIBLE);
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(ApiService.BASE_URL)
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .build();
    
            ApiService apiService = retrofit.create(ApiService.class);
            Call<String> call = apiService.getMovies();
    
            call.enqueue(new Callback<String>() {
                @Override
                public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
                    if (response.isSuccessful()) {
                        if (response.body() != null) {
                            try {
                                JSONObject jsonObject = new JSONObject(response.body());
                                JSONArray jsonArray = jsonObject.getJSONArray("movies");
    
                                for (int i = 0; i < jsonArray.length(); i++) {
                                    JSONObject jObj = jsonArray.getJSONObject(i);
    
                                    String title = jObj.getString("name");
                                    String imageUrl = jObj.getString("imageUrl");
    
                                    Movie item = new Movie();
                                    item.setName(title);
                                    item.setImage(imageUrl);
    
                                    movieList.add(item);
    
                                    mProgressBar.setVisibility(View.GONE);
                                }
    
                                movieAdapter.notifyDataSetChanged();
    
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    } else {
                        mProgressBar.setVisibility(View.GONE);
                        Toast.makeText(MainActivity.this, R.string.string_some_thing_wrong, Toast.LENGTH_SHORT).show();
                    }
                }
    
                @Override
                public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
                    mProgressBar.setVisibility(View.GONE);
                    Log.w(TAG, "loadData: failed!", t);
                    Toast.makeText(MainActivity.this, R.string.string_some_thing_wrong, Toast.LENGTH_SHORT).show();
                }
            });
    
        } else {
            Toast.makeText(this, R.string.string_internet_connection_not_available, Toast.LENGTH_SHORT).show();
        }
    }

Download Complete Source Code

About the author

Akshay Raj

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *