ProcgerXacker
ProcgerXacker

Reputation: 123

How to read JSON file using Retrofit2, RxJava2 on Kotlin Android

I started learning reactive programming quite recently. I can read API JSON files using Retrofit2, but I don’t know how to do it using reactive programming using RxJava2. If you have links or ready-made code, it would be grateful. I myself tried to implement this task, but it does not work. I did everything according to this link - https://www.learn2crack.com/2017/11/retrofit-and-rxjava-in-kotlin.html, but when I call the Response function in subscribe, nothing works. For example, I try to display it, but nothing is displayed.

MainActivity class


package com.example.json_rxjava

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.example.json_rxjava.MODEL.JsonModel
import com.example.json_rxjava.NETWORK.RequestInterface
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

class MainActivity : AppCompatActivity() {
    private val BASE_URL = "https://learn2crack-json.herokuapp.com/"
    private var mCompositeDisposable: CompositeDisposable? = null
    private var mJsonModelDataList: ArrayList<JsonModel>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        loadJSON()
    }

    private fun loadJSON() {
        val requestInterface = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build().create(RequestInterface::class.java)

        mCompositeDisposable?.add( requestInterface.getData()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe(this::handleResponse)
        )
    }

    private fun handleError(error: Throwable) {
        Log.e("ERROR: ", error.localizedMessage)
    }

    private fun handleResponse(jsonModel: List<JsonModel>) {
        Log.e("LOG TEST", "THIS IS RESPONSE")
        mJsonModelDataList = ArrayList(jsonModel)
        for(i in 0..mJsonModelDataList!!.size-1) {
            Log.e("LOG: ", mJsonModelDataList?.get(i)?.name.toString())
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mCompositeDisposable?.clear()
    }
}

RequestInterface


package com.example.json_rxjava.NETWORK

import com.example.json_rxjava.MODEL.JsonModel
import io.reactivex.Observable
import retrofit2.http.GET

interface RequestInterface {
    @GET("api/android")
    fun getData(): Observable<List<JsonModel>>
}

JsonModel


package com.example.json_rxjava.MODEL

data class JsonModel(
    val version: String,
    val name: String,
    val apiLevel: String
)

Added the following dependencies to build.gradle:


//RxJava and Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

In AndroidManifest added:

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

The program outputs:


D/NetworkSecurityConfig: Using Network Security Config from resource network_security_config debugBuild: true
D/: HostConnection::get() New Host Connection established 0xa3fc0140, tid 8411
D/: HostConnection::get() New Host Connection established 0xa3fc0500, tid 8460
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0xaed85360: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xaed85360: ver 2 0 (tinfo 0xaed831f0)
D/EGL_emulation: eglMakeCurrent: 0xaed85360: ver 2 0 (tinfo 0xaed831f0)
D/EGL_emulation: eglMakeCurrent: 0xaed85360: ver 2 0 (tinfo 0xaed831f0)

Please tell me, if you know what the problem is, or if you have links or ready-made code about how to read API JSON using Retrofit2 and RxJava2 in Kotlin, then discard it please.

Upvotes: 0

Views: 253

Answers (1)

Subhrajyoti Sen
Subhrajyoti Sen

Reputation: 1735

The reason nothing is happening is that you forgot to initialize mCompositeDisposable. So whenever you execute mCompositeDisposable?., that code is skipped because mCompositeDisposable is null.

To fix it, replace the declaration with

private val mCompositeDisposable: CompositeDisposable = CompositeDisposable()

Upvotes: 1

Related Questions