Search code examples
androidapiclasskotlinpublic

Kotlin get a variable/value from one class to another


I´m trying to get variables from one Class to another after an API request with okhttp.

API Request (in my MainActivity): (with the normal class class MainActivity : AppCompatActivity(){ )

fun fetchJson() {
            val url = "https://......./api/.../....."

            val request = Request.Builder().url(url).build()

            val client = OkHttpClient()
            client.newCall(request).enqueue(object: Callback{

                override fun onResponse(call: Call, response: Response) {
                    val body = response?.body?.string()
                     println(body)
                    val gson = GsonBuilder().create()

                    val ApiStats = gson.fromJson(body, ApiStats::class.java)

                }

                override fun onFailure(call: Call, e: IOException) {
                    println("API execute failed")
                }
            })

        }

And the result will be "saved" in a extra Class:

class ApiStats(val apple: String)

And now I want to get the val in my MainActivity class which already mentioned before

I have already seen the possibility with a fun but it didn't seems to work for me...

I have also tried this: class MainActivity(val apiStats: ApiStaats) : AppCompatActivity()

But when I start the app it crashes the process

2020-02-25 13:36:53.466 10543-10543/example.spectre.vision E/AndroidRuntime: FATAL EXCEPTION: main
    Process: example.spectre.vision, PID: 10543
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{example.spectre.vision/example.spectre.vision.MainActivity}: java.lang.InstantiationException: java.lang.Class<example.spectre.vision.MainActivity> has no zero argument constructor
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.InstantiationException: java.lang.Class<example.spectre.vision.MainActivity> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1243)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3182)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 ```

Solution

  • The reason you can't put the property in the Activity constructor is that Android requires all Activities to have no arguments in the constructor. This is not a typical Java or Kotlin requirement, but Android uses the empty constructor to create instances of your Activity via reflection. You can put the property in the body of the class like this:

    class MyActivity: AppCompatActivity() {
        var apiStats: ApiStats? = null
    
        //...
    }
    

    Then there's the matter of getting that data back from your other object. Replace this line:

    val ApiStats = gson.fromJson(body, ApiStats::class.java)
    

    with

    apiStats = gson.fromJson(body, ApiStats::class.java)
    

    You will probably want to follow that line with other code that updates the UI or something.