Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Implementing Retrofit in Your Android Application

Pascal How
September 16, 2018

Implementing Retrofit in Your Android Application

Pascal How

September 16, 2018
Tweet

More Decks by Pascal How

Other Decks in Programming

Transcript

  1. What is Retrofit • Type-Safe REST client using annotations to

    describe HTTP requests • Framework to interact with APIs and sending network requests • Automatically parses downloaded data into a Plain Old Java Object
  2. Old Way: Async Tasks • No screen orientation support •

    No ability to cancel network calls • No easy way to make API calls in parallel
  3. AsyncTasks public class HttpGetRequest extends AsyncTask < String, Void, String

    > { public static final String REQUEST_METHOD = "GET"; public static final int READ_TIMEOUT = 15000; public static final int CONNECTION_TIMEOUT = 15000; @Override protected String doInBackground(String...params) { String stringUrl = params[0]; String result; String inputLine; try { //Create a URL object holding our url URL myUrl = new URL(stringUrl); //Create a connection HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection(); //Set methods and timeouts connection.setRequestMethod(REQUEST_METHOD); connection.setReadTimeout(READ_TIMEOUT); connection.setConnectTimeout(CONNECTION_TIMEOUT); //Connect to our url connection.connect() //Create a new InputStreamReader InputStreamReader streamReader = new InputStreamReader(connection.getInputStream()); //Create a new buffered reader and String Builder BufferedReader reader = new BufferedReader(streamReader); StringBuilder stringBuilder = new StringBuilder(); //Check if the line we are reading is not null while ((inputLine = reader.readLine()) != null) { stringBuilder.append(inputLine); } //Close our InputStream and Buffered reader reader.close(); streamReader.close(); //Set our result equal to our stringBuilder result = stringBuilder.toString(); } catch (IOException e) { e.printStackTrace(); result = null; } return result; } protected void onPostExecute(String result) { super.onPostExecute(result); } } Now imagine making many network calls at the same time!
  4. Why Use Retrofit? • Super easy to use! ◦ Only

    define URLs to hit ◦ JSON Parsing is all done for you • Supports async requests with minimal code ◦ NO MORE ASYNCTASKS + Manual Json parsing • Great Documentation and Community
  5. Retrofit For Dummies! • Add dependencies • Describe API endpoints

    • JSON Mapping • Prepare Request With OkHttp and Retrofit
  6. Setting Up Retrofit Set Retrofit as a dependency in gradle

    dependencies { compile 'com.squareup.retrofit2:retrofit:2.2.0' compile 'com.squareup.retrofit2:converter-gson:2.2.0' } Android Network Permission <uses-permission android:name="android.permission.INTERNET" /> JSON Converter
  7. Leveraging OkHttp OkHttpClient • This is what makes the actual

    HTTP request within Retrofit • More efficient than standard Java I/O library for reading and writing data • Works best with a single instance across application ◦ Each new instance gets its own private connection pool ◦ Creating many will prevent connection reuse ◦ Each connection pool holds its own set of connections alive ◦ Too many connection pools will exhaust memory
  8. Describing API Endpoints public interface GitHubService { @GET("/users/pascalhow/repos") Call <List<Repo>>

    listRepos(); @POST("/user/info") Call <List<UserInfo>> updateUserInfo(@Body UserInfo userInfo); @DELETE("/user") Call <Void> deleteUser(); }
  9. JSON Mapping • Requests to a server and responses from

    the server not Java objects • Usually JSON format TIPS • Automatically create Java class using jsonschema2pojo
  10. JSON Mapping public class UserInfo { @SerializedName("id") private int userId;

    @SerializedName("name") private String userName; @SerializedName("activities") private Activities activities; // Getters and setters }
  11. Making the Request Retrofit REST Client Retrofit retrofit = new

    Retrofit.Builder() .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); GitHubService service = retrofit.create(GitHubService.class); Specify the base URL Add the JSON converter Implement the service
  12. Making the Request // Asynchronous HTTP request to the remote

    webserver Call <List<Repo>> repos = service.listRepos(); call.enqueue(new Callback <List<Contributor>> () { @Override void onResponse(Response <List<Contributor>> contributors) { // Display some data } @Override void onFailure(Throwable t) { // Handle error } });
  13. Path Parameters Dynamic URLs @GET("/users/{user}/repos") Call <List<GitHubRepo>> getReposUsingDynamicUrl(@Path("user") String user);

    // Fetch a list of GitHub repos Call <List<GitHubRepo>> call = service.getReposUsingDynamicUrl("pascalhow"); Very useful when interacting with app!
  14. Query Parameters • Request data not part of URL •

    Not added to annotation URL like path parameters https://api.github.com/repos/jamescoggan/android-tech-talks-april/commits?author=pascalhow @GET("/repos/{user}/{repos}/commits") Call <List<Commit>> getCommits( @Path("user") String user, @Path("repos") String repos, @Query("author") String author);
  15. Posting Data @POST("/commits") Call <Commit> createCommit(@Body Commit commit); public class

    Commit { private String author; private String message; // Getter and setter } Commit commit = new Commit("pascalhow", "Initial commit"); Call <Commit> call = GitHubService.createCommit(commit); call.enqueue(new Callback <Commit> () {}); { "author": "pascalhow", "message": "Initial commit" }
  16. Authentication • What if an API call needs authorisation? •

    HTTP headers passes additional information with request or response • Use OkHttp to generate credentials
  17. Authentication • What if we need to make several calls

    that all need authentication? Use Interceptors! • Interceptors are powerful mechanisms that can monitor, rewrite and retry calls
  18. Authentication OkHttpClient httpClient = new OkHttpClient().Builder() .addInterceptor(new Interceptor() { @Override

    public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request.Builder builder = originalRequest.newBuilder() .header("Authorization", Credentials.basic("username", "password")); Request newRequest = builder.build(); return chain.proceed(newRequest); } }).build(); Add an interceptor to OkHttp Add credentials to the Authorisation header
  19. Retrofit and RxJava • Retrofit supports RxJava! • Simplifies code

    further with lambdas • Good when making several network calls before updating UI
  20. Retrofit and RxJava Add dependency to gradle compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0' public

    interface GitHubService { @GET("/users/{user}/repos") Observable <List<GitHubRepo>> getReposUsingRxJava(@Path("user") String user); }
  21. Retrofit and RxJava Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create())

    .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(okHttpClient) .build(); GitHubService service = retrofit.create(GitHubService.class); Add RxJava adapter to Retrofit!
  22. Retrofit and RxJava service.getReposUsingRxJava(accountName) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber <List<GitHubRepo>> ()

    { @Override public void onCompleted() { // Request completed } @Override public void onError(Throwable e) { // Handle error } @Override public void onNext(List < GitHubRepo > gitHubRepos) { displayData(gitHubRepos); } });
  23. Conclusion • What Retrofit is • Implementing Retrofit in your

    Android app • Explored HTTP requests • Adding Authentication • Using Retrofit with RxJava