OkHttp client.newcall(запрос).enqueue ... получение нулевого указателя
Я пытаюсь установить вар JSON, но я получаю нулевой указатель в конце. Любые идеи, как это исправить? еще новичок с андроидом
class Requester(activity: Activity) {
...
var json : Info? = null
...
fun getData (counter : Int) {
println("frist attemp"+json)// here it is null as it should be
var show = 5*counter
var url = "https://reqres.in/api/users?page=1&per_page=$show"
var 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()
val gson = GsonBuilder().create()
json = gson.fromJson(body,Info::class.java)//it should be init here
activity.runOnUiThread {
dataSize = json!!.total
val adapter = UsersAdapter(activity ,json!!,activity)
if(activity is MainActivity)
activity.recycler_View.adapter = adapter
}
isLoading=false
toast.cancel()
}
override fun onFailure(call: Call?, e: IOException?) {
activity.runOnUiThread {
val adapter = UsersAdapter(activity ,Info(0,0,0,0,
listOf(Data(0,"NO CONECTION","",""))),activity)
activity.recycler_View.adapter = adapter
Toast.makeText(activity,"Failed to connect", Toast.LENGTH_SHORT).show()
toast.cancel()
}
isLoading=false
}
})
println("end "+json)// here i get NULL any ideas why ?
}
}
Информация о классе:
class Info(val page: Int,
val per_page: Int,
val total: Int,
val total_pages: Int,
val data: List<Data>)
Данные класса:
class Data(val id: Int,
val first_name: String,
val last_name: String,
val avatar: String)
Класс UserActivity:
class UserActivity : AppCompatActivity(){
var id : Int =0
val requester : Requester = Requester(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
id = intent.getIntExtra("id",0)
display()
}
private fun display() {
textView_ID_DEFINED.setText("$id")
requester.getData(id/3+1)
var info : Info? = requester.json
println("requester="+requester)
println("requester.info= "+requester.json)
if (info !=null){
for (i in 0..info.data.size){
if (id == info.data[i].id){
println("ahoj")
}
}
}
}
}
Трассировки стека:
I / Временная шкала: Временная шкала: Activity_launch_request id:com.example.android.zadanie Время:197846234 I/System.out:requestter=com.example.android.zadanie.Requester@127852b requestter.info= null I/ Временная шкала: Хронология: Activity_idle id: android.os.BinderProxy@5994e58 время:197846419 I/System.out: mid com.example.android.zadanie.Info@e380f1b
1 ответ
Место, где ваш json
переменная должна быть инициализирована (т.е. fun onResponse
) вызывается асинхронно, когда HTTP-запрос завершен. Это означает, что getData
заканчивается до того, как обратный вызов на самом деле вызывается, и именно поэтому вы получаете null
,
Почему ваш обратный вызов вызывается асинхронно? Ну вот как enqueue
реализован, и его главное преимущество заключается в том, что он выполняет HTTP-запрос в отдельном потоке, чтобы ваш пользовательский интерфейс не зависал. Однако при работе с асинхронными обратными вызовами вы должны учитывать, что ваш код может выполняться в любой момент времени, даже когда ваше приложение больше не находится на переднем плане (представьте себе сценарий, когда пользователь получает телефонный звонок во время работы вашего приложения)