Retrieve and Display data from the Internet into your Android App with Retrofit.

In this tutorial, we'll build an app that connects to a web service to retrieve and display data. We'll be using the Retrofit library to connect to a REST web service on the internet and get a response. For now, we focus on displaying raw JSON. And of course, we'll be using Android Studio as our IDE.

Step 1: Create a new project and call it DisplayData

  • Open Android Studio if it is not already opened.
  • In the main Welcome to Android Studio dialog, click Start a new Android Studio project.
  • The Choose your project dialog appears. Select Empty Activity as shown below, and click Next.
  • In the Configure your project dialog, enter "DisplayData" for the Name and click Finish

Step 2: Add various dependencies:

  • Inside the dependencies block, add the Gradle dependency for the Retrofit and ViewModel.
//Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
//ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
  • Add the data binding dependency to Gradle
android{...

    buildFeatures {
        dataBinding true
    }
  • Apply the kotlin-kapt plugin at the top of the build.gradle file
 id 'kotlin-kapt'
  • Ensure the support for Java 8 language features are added
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

Click on Sync Now

Step 3: Setup ViewModel and connect with MainActivity

  • Create a new Kotlin class called DisplayDataViewModel class and make the class extend the abstract class ViewModel
class OverviewViewModel : ViewModel() {
}
  • In DisplayDataViewModel, we create both internal and external LiveData for the response String
private val _response = MutableLiveData<String>()

val response: LiveData<String>
    get() = _response
  • At the top of MainActivity class, make the MainActivity lazily initializes the DisplayDataViewModel.
private val viewModel: DisplayDataViewModel by lazy {
    ViewModelProvider(this).get(DisplayDataViewModel::class.java)
}
  • Inside the onCreateView() method. Inflate the MainActivity layout using data binding. Comment out or delete the setContentView line of code.
//setContentView(R.layout.activity_main)
val binding: ActivityMainBinding =
    DataBindingUtil.setContentView(this, R.layout.activity_main)
  • In the activity_main.xml layout, add the data binding for the view model. This imports DisplayDataViewModel. (Make layout view the root view).
<layout ...>
    <data>
        <variable
            name="displayDataViewModel"
            type="com.example.marsproperty.DisplayDataViewModel" />
    </data>
</layout>
  • Create the Constraintlayout, and add the TextView inside. Bind the response from the ViewModel to the TextView
<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{displayDataViewModel.response}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • Inside the MainActivity file, Specify the MainActivity view as the lifecycle owner of the binding and pass the displayDataViewModel into the data binding.
binding.lifecycleOwner = this
binding.displayDataViewModel = viewModel

Step 4: Implement the DisplayDataApiService

  • Create DisplayDataApiService.kt and add a constant Base Url at the top of the file.
private const val BASE_URL = "https://jsonplaceholder.typicode.com/"
  • Below the constant, use a Retrofit builder to create a Retrofit object
private val retrofit = Retrofit.Builder()
   .addConverterFactory(ScalarsConverterFactory.create())
   .baseUrl(BASE_URL)
   .build()
  • Just below the call to the Retrofit builder, define an interface that defines how Retrofit talks to the web server using HTTP requests.
interface DisplayDataApiService {
    @GET("todos")
    fun getProperties():
            Call<String>
}
  • Below the DisplayDataApiService interface, define a public object called DataApi to initialize the Retrofit service.
object DataApi {
    val retrofitService : DisplayDataApiService by lazy { 
       retrofit.create(DisplayDataApiService::class.java) }
}

Step 5: Call the web service in DisplayDataViewModel.

  • In the DisplayDataViewModel, we create the init block and call getDetails() method inside.
init {
    getDetails()
}
  • Create the getDetails method
private fun getDetails() {

}
  • Next we'll call the web service in DisplayDataViewModel. Inside the getDetails() method, add the code below,
DataApi.retrofitService.getProperties().enqueue( 
   object: Callback<String> {
})
  • Click on the word object, which is underlined in red. Select Code > Implement methods. Select both onResponse() and onFailure() from the list.
override fun onFailure(call: Call<String>, t: Throwable) {
       TODO("not implemented") 
}

override fun onResponse(call: Call<String>, 
   response: Response<String>) {
       TODO("not implemented") 
}
  • In onFailure(), delete the TODO and set the _response to a failure message, as shown below.
override fun onFailure(call: Call<String>, t: Throwable) {
   _response.value = "Failure: " + t.message
}
  • In onResponse(), delete the TODO and set the _response to the response body.
override fun onResponse(call: Call<String>, 
   response: Response<String>) {
      _response.value = response.body()
}

Step 6: Define the internet permission.

Open app/manifests/AndroidManifest.xml. Add this line just before the tag:

<uses-permission android:name="android.permission.INTERNET" />

Compile and run the app. If everything is working correctly with your internet connection, you see...

Screenshot_1607409656a.png Cover photo by Luca Bravo on Unsplash

No Comments Yet