Невозможно получить любую строку при вызове REST API - PullRequest
0 голосов
/ 28 февраля 2019
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.lang.Exception

...

private val client = OkHttpClient()

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

    val tvDisplay: TextView = findViewById(R.id.displayTV) as TextView
    tvDisplay.setOnClickListener {
        tvDisplay.text = run("https://jsonplaceholder.typicode.com/todos/1")
    }
}

@Throws(IOException::class)
fun run(url: String): String {
    val request = Request.Builder()
        .url(url)
        .build()
    try {
        client.newCall(request).execute().use { response -> return response.body().toString() }
    } 
    catch (e: Exception) {
        return e.message.toString()
    }
}

Использование android studio и kotlin.Пытаясь вызвать API, но все, что я получаю, это NULL вместо строки, которую он должен получать.

Кроме того, как мне добавить базовую аутентификацию для этого (имя пользователя / пароль), если API требовал этого?

И что делает "@Throws"?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Более подробное объяснение через код

@Throws(IOException::class) // If IOException occur it will throw error to its parent the one that call to this function so you do not need try catch in this function
fun run(url : String) : Response{

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

    val client = OkHttpClient()
    return client.newCall(request).execute()
}

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

    val tvDisplay: TextView = findViewById(R.id.displayTV) as TextView
    val thread = object : Thread() {    //Always use another thread from UIthread so UI will not lock while waiting get response from API
    override fun run() {
            try{
                val _response = run("https://jsonplaceholder.typicode.com/todos/1").body()!!.string()

                runOnUiThread { //Change to UI thread again if you need change somthing in UI
                    tvDisplay.setText(_response)
                }
            }
            catch(e: Excpetion){
                Log.d("Exception", e.toString())    //if anything error it goes here
            }
        }
    }
    thread.start()
}
0 голосов
/ 28 февраля 2019

Для начала я бы посоветовал изучить дооснащение , поскольку лично мне легче работать (хотя это может быть излишне, если вы делаете только один или два вызова REST) ​​

Я бы, вероятно, также сделал

client.newCall(request).enqueue(object: Callback {
    override fun onResult(call: Call, response: Response) {
        if (response.isSuccessful()) {
            return@run response.body.toString()
        }
    }
)}

асинхронным.

Аутентификация - это боль, которую нужно добавить в OkHttp imo, и на нее лучше всего ответить здесь ,и намного проще в Retrofit.

Наконец, Throws помечает функцию как имеющую потенциал для выброса Exception при вызове из кода Java (поскольку Kotlin и Java могут сосуществовать)

...