0

Solution:

class MainActivity : AppCompatActivity() {
    lateinit var playerStats: PlayerStats

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Picasso.get().load("https://...../....../example.png").into(Viewer)
        var PlayerName: String = ""

        fun fetchJson() {
            val url = "https://my.api.site/example/"
            val request = Request.Builder().url(url).build()
            val client = OkHttpClient()
            client.newCall(request).enqueue(object : Callback {
                var mainHandler = Handler(this@MainActivity.getMainLooper())
                override fun onResponse(call: Call, response: Response) {
                    mainHandler.post {
                        val body = response.body()?.string()
                        if (body == null) return@post
                        println(body)

                        val gson = GsonBuilder().create()
                        playerStats = gson.fromJson(body, PlayerStats::class.java)
                        println(playerStats)

                        // TODO Now you can access to your view and set every thing to textView
                        textView.text = playerStats.username
                    }
                }

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

        buttonGO.setOnClickListener {
            PlayerName = editText.text.toString()
            fetchJson()
            if (PlayerName == null || PlayerName.trim() == "") {
                println("please input data, input cannot be blank")
            } else {
                Picasso.get().load("https://...../...../" + PlayerName + ".png")
                    .into(Viewer)
                textView.setText(PlayerName).toString()
            }
        }
    }
} ```

I have this code for my api request and it works when I use debugger.

I can see the results in the PlayerStats class but now I have a problem.

But on the MainActivity.class this function don't work:

val url = "https://api.example.com/..../"
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 PlayerStats = gson.fromJson(body, PlayerStats::class.java)
        println(PlayerStats)
    }

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

Stats.class:

class PlayerStats(val username: String  , val level: Double )

I need a way to get access to the val username / val level from MainActivity

class MainActivity(val mystats: PlayerStats) : AppCompatActivity(){

Not works, because of the zero arguments.

If I try to fix:

class MyActivity: AppCompatActivity() {
    var myStats: Stats? = null
//..
}

The IDE say it needs a safe call or a non-null asserted call but if I try this with the non-null asserted call the application crash and i get this error:

2020-03-05 18:58:02.803 23276-23276/my.example.package E/AndroidRuntime: FATAL EXCEPTION: main Process: my.example.package, PID: 23276 kotlin.KotlinNullPointerException at my.example.package.MainActivity$onCreate$1.invoke(MainActivity.kt:31) at my.example.package.MainActivity$onCreate$3.onClick(MainActivity.kt:68) at android.view.View.performClick(View.java:7125) at android.view.View.performClickInternal(View.java:7102) at android.view.View.access$3500(View.java:801) at android.view.View$PerformClick.run(View.java:27336) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) 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)

With the safe call I get null as output


Full code:

MainActivity.class:

package my.example.package

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.GsonBuilder
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.*
import java.io.IOException

class MainActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Picasso.get().load("https://...../....../example.png").into(Viewer)
        var PlayerName: String = ""
        fun fetchJson() {
            val url = "https://my.api.site/example/"
            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 PlayerStats = gson.fromJson(body, PlayerStats::class.java)
                    println(PlayerStats)
                }
                override fun onFailure(call: Call, e: IOException) {
                    println("API execute failed")
                }
            })
        }

        buttonGO.setOnClickListener {
            PlayerName = editText.text.toString()
            fetchJson()
            if (PlayerName == null || PlayerName.trim() == "") {
                println("please input data, input cannot be blank")
            } else {
                Picasso.get().load("https://...../...../" + PlayerName + ".png")
                    .into(Viewer)
                textView.setText(PlayerName).toString()
            }
        }
    }
}

PlayerStats.class:

package my.example.package
class PlayerStats(val username: String  , val level: Double )

1 Answers1

0

Replace this with your code:

class MainActivity : AppCompatActivity() {
    lateinit var playerStats: PlayerStats

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Picasso.get().load("https://...../....../example.png").into(Viewer)
        var PlayerName: String = ""

        fun fetchJson() {
            val url = "https://my.api.site/example/"
            val request = Request.Builder().url(url).build()
            val client = OkHttpClient()
            client.newCall(request).enqueue(object : Callback {
                var mainHandler = Handler(this@MainActivity.getMainLooper())
                override fun onResponse(call: Call, response: Response) {
                    mainHandler.post {
                        val body = response.body()?.string()
                        if (body == null) return@post
                        println(body)

                        val gson = GsonBuilder().create()
                        playerStats = gson.fromJson(body, PlayerStats::class.java)
                        println(playerStats)

                        // TODO Now you can access to your view and set every thing to textView
                        textView.text = playerStats.username
                    }
                }

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

        buttonGO.setOnClickListener {
            PlayerName = editText.text.toString()
            fetchJson()
            if (PlayerName == null || PlayerName.trim() == "") {
                println("please input data, input cannot be blank")
            } else {
                Picasso.get().load("https://...../...../" + PlayerName + ".png")
                    .into(Viewer)
                textView.setText(PlayerName).toString()
            }
        }
    }
} ```

Hassan Alizadeh
  • 103
  • 1
  • 8
  • thx very much... one little problem at `val body = response.body()?.string()` the .body has an error: `Using 'body(): ResponseBody?' is an error. moved to val ` –  Mar 07 '20 at 23:08
  • IDE suggests to replace `val body = response.body()?.string()` with `val body = response.body?.string()` or to replace the usage of `body(): ResponseBody? in whole project –  Mar 08 '20 at 07:17
  • i googled the error but the only thing i found is this https://stackoverflow.com/questions/56913085/getting-an-error-using-body-responsebody-is-an-error-moved-to-val-with-ok –  Mar 08 '20 at 08:31
  • It's not important. It depends on your okHttp version. If the answer was useful, please mark it as answer – Hassan Alizadeh Mar 08 '20 at 08:35
  • found a solution i removed the "()" after body –  Mar 08 '20 at 08:38
  • hey can you help me with this: https://stackoverflow.com/questions/60607465/api-request-okhttp-api-request-via-okhttp-with-two-objects –  Mar 09 '20 at 20:56