1/23

Android Development

Android Networking

2/23

Agenda

3/23

REST API Basic

4/23

Relationship between URI and HTTP methods

HTTP METHODS Collection resource, such as https://api.example.com/collection/ Member resource, such as https://api.example.com/collection/item3
GET Retrieve the URIs of the member resources of the collection resource in the response body. Retrieve representation of the member resource in the response body.
POST Create a member resource in the collection resource using the instructions in the request body. The URI of the created member resource is automatically assigned and returned in the response Location header field. Create a member resource in the member resource using the instructions in the request body. The URI of the created member resource is automatically assigned and returned in the response Location header field.
PUT Replace all the representations of the member resources of the collection resource with the representation in the request body, or create the collection resource if it does not exist. Replace all the representations of the member resource or create the member resource if it does not exist, with the representation in the request body.
PATCH Update all the representations of the member resources of the collection resource using the instructions in the request body, or may create the collection resource if it does not exist. Update all the representations of the member resource, or may create the member resource if it does not exist, using the instructions in the request body.
DELETE Delete all the representations of the member resources of the collection resource. Delete all the representations of the member resource.

Source: https://en.wikipedia.org/wiki/Representational_state_transfer (112019)

5/23

HTTP response status codes

6/23

JSON Basics

7/23

JSON Data Types

For examples visit https://restfulapi.net/json-data-types/

8/23

## JSON Example

{
   "Search":[
      {
         "Title":"I, Robot",
         "Year":"2004",
         "imdbID":"tt0343818",
         "Type":"movie",
         "Poster":"https://m.media-amazon.com/images/M/MV5BNmE1OWI2ZGItMDUyOS00MmU5LWE0MzUtYTQ0YzA1YTE5MGYxXkEyXkFqcGdeQXVyMDM5ODIyNw@@._V1_SX300.jpg"
      },
      {
         "Title":"Robot Revolution: The Making of 'I, Robot'",
         "Year":"2004",
         "imdbID":"tt0427788",
         "Type":"movie",
         "Poster":"N/A"
      },
      {
         "Title":"Day Out of Days: The 'I, Robot' Production Diaries",
         "Year":"2004",
         "imdbID":"tt0457853",
         "Type":"movie",
         "Poster":"N/A"
      },
   ],
   "totalResults":"3",
   "Response":"True"
}
9/23

REST API Clients

10/23

Retrofit

Link: https://square.github.io/retrofit/

11/23

GSON

Link: https://github.com/google/gson

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of. There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.

Goals

Source: https://github.com/google/gson (112019)

12/23

Retrofit Example

  1. Setup project Gradle dependency

Add mavenCentral() to your project build.gradle (the one located next to app folder, not inside)

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
        
    }
}
13/23

Retrofit Example

  1. Setup app Gradle dependency

Add retrofit and gson converter dependency to Gradle

implementation "com.squareup.retrofit2:converter-gson:2.6.1" 
implementation "com.squareup.retrofit2:retrofit:2.6.1"
14/23

Retrofit Example

  1. Create POJO to represent API model

JSON:

{
	"Title": "Ghost in the Shell",
	"Year": "1995",
	"imdbID": "tt0113568",
	"Type": "movie",
	"Poster": "https://m.media-amazon.com/images/M/MV5BYWRiYjQyOGItNzQ1Mi00MGI1LWE3NjItNTg1ZDQwNjUwNDM2XkEyXkFqcGdeQXVyNTAyODkwOQ@@._V1_SX300.jpg"
}

Java Class:

public class Movie {
	public String Title;
	public String Year;
	public String imdbID;
	public String Type;
	public String Poster;
}
15/23

Retrofit Example

  1. Create POJO to represent API array

JSON:

{
"Search": [
	{
		"Title": "Ghost in the Shell",
		"Year": "2017",
		"imdbID": "tt1219827",
		"Type": "movie",
		"Poster": "https://m.media-amazon.com/images/M/MV5BMzJiNTI3MjItMGJiMy00YzA1LTg2MTItZmE1ZmRhOWQ0NGY1XkEyXkFqcGdeQXVyOTk4MTM0NQ@@._V1_SX300.jpg"
	},
	{
		"Title": "Ghost in the Shell",
		"Year": "1995",
		"imdbID": "tt0113568",
		"Type": "movie",
		"Poster": "https://m.media-amazon.com/images/M/MV5BYWRiYjQyOGItNzQ1Mi00MGI1LWE3NjItNTg1ZDQwNjUwNDM2XkEyXkFqcGdeQXVyNTAyODkwOQ@@._V1_SX300.jpg"
	}
	]
}

Java Class:

public class SearchResponse {
	List<Movie> Search;
}
16/23

Retrofit Example

  1. Create API Interface for Retrofit
public interface MovieApi {
	@GET(".")
	Call<SearchResponse> getSearchResult(@Query("s") String movieSearch, @Query("apikey") String apiKey);
}
17/23

Retrofit Example

  1. Initialize GSON + Retrofit and make an API call
List<Movie> movieList = new ArrayList<>();

Gson gson = new GsonBuilder()
		.setLenient()
		.create();

Retrofit retrofit = new Retrofit.Builder()
		.baseUrl("https://www.omdbapi.com/")
		.addConverterFactory(GsonConverterFactory.create(gson))
		.build();

MovieApi movieApi = retrofit.create(MovieApi.class);

String searchString = "Ghost in the Shell";

Call<SearchResponse> call = movieApi.getSearchResult(searchString, "MySecretApiKey");

call.enqueue(new Callback<SearchResponse>() {
	@Override
	public void onResponse(Call<SearchResponse> call, Response<SearchResponse> response) {
		movieList = response.body().Search;
	}

	@Override
	public void onFailure(Call<SearchResponse> call, Throwable t) {
		Log.e("Oh noo.", t.getMessage());
	}
});

We use the public free API from OMDb API for this example. You need to put in your email to get a private API key.

18/23

Image loading with Glide

19/23

Glide gradle dependencies

Add this dependency to your app build.gradle

implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
20/23

Glide basic usage

Load an remote image into a ImageView. + Create a new activty with a ImageView.

Layout XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical">

	<ImageView
		android:id="@+id/imgView"
		android:layout_width="200dp"
		android:layout_height="wrap_content" />
</LinearLayout>
21/23

Glide basic usage

Load an remote image into a ImageView.

Activity

import android.os.Bundle;
import android.widget.ImageView;

import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;

public class GlideActivty extends AppCompatActivity {

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

		String imgUrl = "https://m.media-amazon.com/images/M/MV5BOTlhYTVkMDktYzIyNC00NzlkLTlmN2ItOGEyMWQ4OTA2NDdmXkEyXkFqcGdeQXVyNTAyODkwOQ@@._V1_SX300.jpg";

		ImageView imageView = findViewById(R.id.imgView);

		Glide.with(this).load(imgUrl).into(imageView);
	}
}
22/23

Glide basic usage

Load an remote image into a ImageView.

center

23/23

Glide error & success handling

Glide allows for listening to success and error states. This allows you to handle broken urls or to post process images.

Example show Toast if Glide is unable to show image

String imgUrl = "https://example.com/image.jpg"; //invalid image url
Glide.with(this)
		.load(imgUrl)
		.listener(new RequestListener() {
			@Override
			public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
				Toast.makeText(GlideActivty.this, "Unable to load image", Toast.LENGTH_SHORT).show();
				//TODO show fallback image
				return false;
			}

			@Override
			public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
				return false;
			}
		})
		.into(imageView);