OkHttp client.newcall(request).enqueue ...获取空指针
OkHttp client.newcall(request).enqueue ... getting null pointer
我正在尝试设置 var json,但最后我得到了空指针。任何想法如何解决这一问题 ? android
还是新手
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 信息:
class Info(val page: Int,
val per_page: Int,
val total: Int,
val total_pages: Int,
val data: List<Data>)
Class数据:
class Data(val id: Int,
val first_name: String,
val last_name: String,
val avatar: String)
Class 用户活动:
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/Timeline:时间线:Activity_launch_request id:com.example.android.zadanie time:197846234
I/System.out:requester=com.example.android.zadanie.Requester@127852b
requester.info=空
I/Timeline: 时间线: Activity_idle id: android.os.BinderProxy@5994e58 time:197846419
I/System.out: mid com.example.android.zadanie.Info@e380f1b
当 HTTP 请求完成时,您的 json
变量应该被初始化的地方(即 fun onResponse
)被异步调用。这意味着 getData
在 之前 实际调用回调,这就是为什么你得到 null
.
为什么你的回调被异步调用?嗯,这就是 enqueue
的实现方式,它的主要优点是它在单独的线程中运行 HTTP 请求,这样您的 UI 就不会冻结。但是,在使用异步回调时,您必须考虑到您的代码可能会在任何时间点执行,即使您的应用程序不再处于前台(想象一个场景,当您的应用程序处于运行状态时,用户收到 phone 调用运行)
我正在尝试设置 var json,但最后我得到了空指针。任何想法如何解决这一问题 ? android
还是新手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 信息:
class Info(val page: Int,
val per_page: Int,
val total: Int,
val total_pages: Int,
val data: List<Data>)
Class数据:
class Data(val id: Int,
val first_name: String,
val last_name: String,
val avatar: String)
Class 用户活动:
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/Timeline:时间线:Activity_launch_request id:com.example.android.zadanie time:197846234 I/System.out:requester=com.example.android.zadanie.Requester@127852b requester.info=空 I/Timeline: 时间线: Activity_idle id: android.os.BinderProxy@5994e58 time:197846419 I/System.out: mid com.example.android.zadanie.Info@e380f1b
当 HTTP 请求完成时,您的 json
变量应该被初始化的地方(即 fun onResponse
)被异步调用。这意味着 getData
在 之前 实际调用回调,这就是为什么你得到 null
.
为什么你的回调被异步调用?嗯,这就是 enqueue
的实现方式,它的主要优点是它在单独的线程中运行 HTTP 请求,这样您的 UI 就不会冻结。但是,在使用异步回调时,您必须考虑到您的代码可能会在任何时间点执行,即使您的应用程序不再处于前台(想象一个场景,当您的应用程序处于运行状态时,用户收到 phone 调用运行)