这段时间用kotlin做okhttp踩了不少的坑,今天2019.4.12 23:40来总结一下这部分内容,作为一名刚刚上手的kotlin的新手确实走了很多的弯路,包括okhttp的很多用法,有些是在java里面有所区别的。
我做的是一个上传位置的功能。
先把我的demo拿上来:
class UpLocationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_up_location)
btn_location_upload.setOnClickListener(){
val location:Location= Location()
val intent=getIntent()
val bd:Bundle=intent.getExtras()//获取前一页传过来的数据
location.address=bd.getString("address")
location.latitude=bd.getDouble("latitude")
location.longitude=bd.getDouble("Longitude")
Log.i("显示提交的位置信息 : ",location.toString())
val url="http://39.96.23.140:8080/Spai/"+"location/insert"
val mediaType = MediaType.parse("text/x-markdown; charset=utf-8")
val request = Request.Builder()
.url(url)
.post(RequestBody.create(mediaType, location.toString()))
.build()
val okHttpClient = OkHttpClient()
val intent1=Intent(this,MainActivity::class.java)
okHttpClient.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.d("请求失败", "onFailure: " + e.message)
Toast.makeText(applicationContext,"位置提交失败",Toast.LENGTH_SHORT).show()
}
@Throws(IOException::class)
override fun onResponse(call: Call, response: Response) {
Log.d("消息体:", response.protocol().toString() + " " + response.code() + " " + response.message())
val headers = response.headers()
Looper.prepare()
Toast.makeText(applicationContext,"位置提交成功",Toast.LENGTH_SHORT).show()
startActivity(intent1)
Looper.loop()
}
})
}
}
}
其中有两个比较重要的点:
Intent的定义要在http线程的外面,在里面会报错,所以在里面跳转页面的时候要加上
Looper当中再进行startActivity(intent1);
这个来运行这个startActivity,否则跳转失效
2.第二个要注意的点是如果要toast显示的话要用Looper来前后包裹一下,否则也报错。
原因的是okhttp开启了单独的线程,在其中操作的话需要Looper,来前后包裹一下具体原因我也没有研究过。
之前尝试过把okhttp单独提出来做一个小的网络工具类,但是没有成功。现在还是把他放在了Activity里面。我之前遇到的一个问题是在请求到参数以后,无法把okhttp中请求结果返回到主线程当中,一直没有找到很好的解决方法,其中使用了handler,Thread线程等方法,都没有能成功,可能是我的代码有问题,希望有能了解这一方面比较深的朋友可以讲一下。