Access GitHub RESTful API via Retrofit from Android

Capture-d’écran-2015-07-22-à-10.09.55.png

Introduction to Retrofit

RESTful services are well suited for providing content to small footprint devices like smartphones and tablets. If you want to interact with a backend from your Android app, you may choose to interact with a REST service. Retrofit is a REST Client for Android and Java by Square.This library is easy learn and has more features.This is beginner friendly compared to other Networking libraries.You can GET, POST, PUT, DELETE etc using this library. You can get the documentation in the square site!

The official website states it as Its a type-safe REST client for Android and Java. Alternatively, you can try Volley or native Asynctask but Retrofit is much more easy & time saver in every operation! So now, let's try to access github RESTful api via Retrofit from Android (honho)

Retrofit Library Setup in Android

retrofit_banner.png

At first create a new project in Android Studio.To setup retrofit, you need to write like below in the dependencies of the gradle file:

compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'

Alternatively, Jar Download: Click here!

You can check for the updated version in their official site here: http://square.github.io/retrofit/ . Retrofit is refactored a lot from v1.9 to v2.0.0-beta1, so it's better not to go under v2.0.0-beta1 (ifyouknowwhatimean)

Basic Configuration for Retrofit

To use Retrofit, we need to create 3 Java classes.

  1. POJO (Plain Old Java Object) or Model Class : The json retrieved from the server is added to this class.
  2. Service Interface : We need to create an interface for managing url calls like GET,POST..etc.
  3. RestAdapter Class : This is RestClient Class. Gson is used in default for the retrofit.

Now, Let's code!

From the github api (https://api.github.com/), we can access the user info by "/users/{username}".

  1. Firstly, let's create a POJO class GitHubUser.java according to the api of user model as following.
package com.licon.retrofit;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class GitHubUser {

	@Expose
	private String login;
	@Expose
	private Integer id;
	@SerializedName("avatar_url")
	@Expose
	private String avatarUrl;
	@SerializedName("gravatar_id")
	@Expose
	private String gravatarId;
	@Expose
	private String url;
	@SerializedName("html_url")
	@Expose
	private String htmlUrl;
	@SerializedName("followers_url")
	@Expose
	private String followersUrl;
	@SerializedName("following_url")
	@Expose
	private String followingUrl;
	@SerializedName("gists_url")
	@Expose
	private String gistsUrl;
	@SerializedName("starred_url")
	@Expose
	private String starredUrl;
	@SerializedName("subscriptions_url")
	@Expose
	private String subscriptionsUrl;
	@SerializedName("organizations_url")
	@Expose
	private String organizationsUrl;
	@SerializedName("repos_url")
	@Expose
	private String reposUrl;
	@SerializedName("events_url")
	@Expose
	private String eventsUrl;
	@SerializedName("received_events_url")
	@Expose
	private String receivedEventsUrl;
	@Expose
	private String type;
	@SerializedName("site_admin")
	@Expose
	private Boolean siteAdmin;
	@Expose
	private String name;
	@Expose
	private String company;
	@Expose
	private String blog;
	@Expose
	private String location;
	@Expose
	private String email;
	@Expose
	private Boolean hireable;
	@Expose
	private Object bio;
	@SerializedName("public_repos")
	@Expose
	private Integer publicRepos;
	@SerializedName("public_gists")
	@Expose
	private Integer publicGists;
	@Expose
	private Integer followers;
	@Expose
	private Integer following;
	@SerializedName("created_at")
	@Expose
	private String createdAt;
	@SerializedName("updated_at")
	@Expose
	private String updatedAt;

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getAvatarUrl() {
		return avatarUrl;
	}

	public void setAvatarUrl(String avatarUrl) {
		this.avatarUrl = avatarUrl;
	}

	public String getGravatarId() {
		return gravatarId;
	}

	public void setGravatarId(String gravatarId) {
		this.gravatarId = gravatarId;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getHtmlUrl() {
		return htmlUrl;
	}

	public void setHtmlUrl(String htmlUrl) {
		this.htmlUrl = htmlUrl;
	}

	public String getFollowersUrl() {
		return followersUrl;
	}

	public void setFollowersUrl(String followersUrl) {
		this.followersUrl = followersUrl;
	}

	public String getFollowingUrl() {
		return followingUrl;
	}

	public void setFollowingUrl(String followingUrl) {
		this.followingUrl = followingUrl;
	}

	public String getGistsUrl() {
		return gistsUrl;
	}

	public void setGistsUrl(String gistsUrl) {
		this.gistsUrl = gistsUrl;
	}

	public String getStarredUrl() {
		return starredUrl;
	}

	public void setStarredUrl(String starredUrl) {
		this.starredUrl = starredUrl;
	}

	public String getSubscriptionsUrl() {
		return subscriptionsUrl;
	}

	public void setSubscriptionsUrl(String subscriptionsUrl) {
		this.subscriptionsUrl = subscriptionsUrl;
	}

	public String getOrganizationsUrl() {
		return organizationsUrl;
	}

	public void setOrganizationsUrl(String organizationsUrl) {
		this.organizationsUrl = organizationsUrl;
	}

	public String getReposUrl() {
		return reposUrl;
	}

	public void setReposUrl(String reposUrl) {
		this.reposUrl = reposUrl;
	}

	public String getEventsUrl() {
		return eventsUrl;
	}

	public void setEventsUrl(String eventsUrl) {
		this.eventsUrl = eventsUrl;
	}

	public String getReceivedEventsUrl() {
		return receivedEventsUrl;
	}

	public void setReceivedEventsUrl(String receivedEventsUrl) {
		this.receivedEventsUrl = receivedEventsUrl;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public Boolean getSiteAdmin() {
		return siteAdmin;
	}

	public void setSiteAdmin(Boolean siteAdmin) {
		this.siteAdmin = siteAdmin;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public String getBlog() {
		return blog;
	}

	public void setBlog(String blog) {
		this.blog = blog;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Boolean getHireable() {
		return hireable;
	}

	public void setHireable(Boolean hireable) {
		this.hireable = hireable;
	}

	public Object getBio() {
		return bio;
	}

	public void setBio(Object bio) {
		this.bio = bio;
	}

	public Integer getPublicRepos() {
		return publicRepos;
	}

	public void setPublicRepos(Integer publicRepos) {
		this.publicRepos = publicRepos;
	}

	public Integer getPublicGists() {
		return publicGists;
	}

	public void setPublicGists(Integer publicGists) {
		this.publicGists = publicGists;
	}

	public Integer getFollowers() {
		return followers;
	}

	public void setFollowers(Integer followers) {
		this.followers = followers;
	}

	public Integer getFollowing() {
		return following;
	}

	public void setFollowing(Integer following) {
		this.following = following;
	}

	public String getCreatedAt() {
		return createdAt;
	}

	public void setCreatedAt(String createdAt) {
		this.createdAt = createdAt;
	}

	public String getUpdatedAt() {
		return updatedAt;
	}

	public void setUpdatedAt(String updatedAt) {
		this.updatedAt = updatedAt;
	}
}

I know, this is a long file (facepalm)

  1. Now, let's create a service class namely GitHubService.java.
package com.licon.retrofit;

import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Path;

public interface GitHubService {
	@GET("/users/{username}")
	Call<GitHubUser> getUser(@Path("username") String username);
}

You can notice the working flow of getting data via retrofit in the above service class.

  1. Now, time to layout design. I have done this demo project using one screen, so here is the activity_main.xml file.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="10dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="@string/hint_write_github_username"
        android:layout_below="@+id/text_view"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:textSize="14sp"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_blue_dark"
        tools:text="Get Github Info"/>

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:layout_marginTop="5dp"/>

    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textSize="12sp"
        android:textColor="@android:color/black"
        android:gravity="center"
        tools:text="Your github info here"/>

</LinearLayout>
  1. Finally, the MainActivity.java file to test the Retrofit! (code)
package com.licon.retrofit;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.squareup.okhttp.ResponseBody;

import java.io.IOException;

import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;

public class MainActivity extends ActionBarActivity {

	private Button mClick;
	private TextView mTextView;
	private EditText mEditUser;
	private ProgressBar mProgressbar;
	public final static String API = "https://api.github.com";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mClick = (Button) findViewById(R.id.button);
		mTextView = (TextView) findViewById(R.id.text_view);
		mEditUser = (EditText) findViewById(R.id.edit_text);
		mProgressbar = (ProgressBar) findViewById(R.id.progress_bar);
		mProgressbar.setVisibility(View.INVISIBLE);
		mClick.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String user = mEditUser.getText().toString();
				mProgressbar.setVisibility(View.VISIBLE);

				Retrofit retrofit = new Retrofit.Builder()
						.baseUrl(API)
						.addConverterFactory(GsonConverterFactory.create())
						.build();

				GitHubService git = retrofit.create(GitHubService.class);
				Call call = git.getUser(user);
				call.enqueue(new Callback<GitHubUser>() {
					@Override
					public void onResponse(Response<GitHubUser> response) {
						GitHubUser model = response.body();

						if (model==null) {
							//404 or the response cannot be converted to GitHubUser.
							ResponseBody responseBody = response.errorBody();
							if (responseBody!=null) {
								try {
									mTextView.setText("responseBody = "+responseBody.string());
								} catch (IOException e) {
									e.printStackTrace();
								}
							} else {
								mTextView.setText("responseBody = null");
							}
						} else {
							//200
							mTextView.setText("Github Name : "+model.getName()
									+"\nCompany Name : "+model.getCompany()
									+"\nEmail : "+model.getEmail()
									+"\nLocation : "+model.getLocation());
						}
						mProgressbar.setVisibility(View.GONE);
					}

					@Override
					public void onFailure(Throwable t) {
						mTextView.setText("t = "+t.getMessage());
						mProgressbar.setVisibility(View.GONE);
					}
				});

			}
		});
	}
}
  1. Don't forget to add internet permission in your Manifest file! (yaoming)
<uses-permission android:name="android.permission.INTERNET"/>

Okay, it's done!

Now, you can test your project by your github user name like below (dance3)

rsz_1rsz_screenshot_from_2015-12-02_143708.png

Reference:

Happy Coding!