【问题标题】:OkHttp client.newcall(request).enqueue ... getting null pointerOkHttp client.newcall(request).enqueue ...获取空指针
【发布时间】:2019-04-07 10:14:55
【问题描述】:

我正在尝试设置 var 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)

类用户活动:

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.zadnie time:197846234 I/System.out:requester=com.example.android.zadanie.Requester@127852b 请求者信息=空 I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@5994e58 time:197846419 I/System.out:中 com.example.android.zadanie.Info@e380f1b

【问题讨论】:

    标签: android kotlin okhttp enqueue


    【解决方案1】:

    当 HTTP 请求完成时,你的 json 变量应该被初始化的地方(即fun onResponse)被异步调用。这意味着getData 在实际调用回调之前结束,这就是你得到null 的原因。

    为什么你的回调被异步调用?嗯,这就是enqueue 的实现方式,它的主要优点是它在单独的线程中运行HTTP 请求,这样你的UI 就不会冻结。但是,在使用异步回调时,您必须考虑到您的代码可能会在任何时间点执行,即使您的应用程序不再处于前台(想象一下用户在您的应用程序运行时接到电话的场景)

    【讨论】:

    • 你应该只使用回调内部的json,你确定它不为空(假设反序列化没有失败)
    • “json”是用“body”定义的,“body”是用“response”定义的,它来自于被覆盖的方法,所以我不能从那里提取它
    • 你的 NPE 发生在哪里?
    • 等等,你不能在var info: Info? = requester.json 有 NPE,因为这意味着requester 为空,但在这种情况下,你的代码之前会失败,至少在上面 1 行.您介意使用完整的堆栈跟踪更新您的问题吗?
    • 我不能这样做,因为我的声誉很低:/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多