我想在点击按钮时在我的Android应用程序中发出请求。在Python中,我可以这样做:
import requests
params = {
'param1':some_string,
'param2':some_int,
'param3':another_string
}
requests.post("https://some.api.com/method/some.method", params=params)
当我按下按钮时,我想在Kotlin做同样的事情。我尝试使用Fuel和khhtp执行此操作,但没有成功 - 应用程序在按下按钮后立即崩溃,负责发送请求。
UPD:我用过的东西:
的AndroidManifest.xml
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...
的build.gradle
dependencies {
...
compile 'com.github.jkcclemens:khttp:0.1.0'
...
}
MainActivity.kt
fun request(){
var message = "message"
var uid = "123456" //I wanted to use it as int, but mapOf didn't allow me
var token = "token"
val payload = mapOf("token" to token, "user_id" to uid, "message" to message)
get("https://some.api.com/method/some.method", params=payload)
val popup = Toast.makeText(this,"Message sent!",Toast.LENGTH_LONG)
popup.show()
}
activity_main.xml中
<Button
...
android:onClick="request" />
这是khhtp的例子,Fuel的一个消失了。
UPD2。 Logcat输出的一部分:
答案 0 :(得分:0)
您只需要查看堆栈跟踪即可找到问题。代码抛出NetworkOnMainThreadException。当您尝试从Android的主要(通常称为UI)线程中访问网络时会发生这种情况。这个question对此问题有一些很好的答案,但是不要试图使用AsyncTask
,而是确保阅读所选网络库的文档,并了解如何在不同的线程上进行调用。
答案 1 :(得分:0)
我不确定这是否是您问题的根源,但您的请求方法签名应该是:
fun request(view: View)
{
}
答案 2 :(得分:0)
正如其他成员所回答的那样,您的代码正在主线程上调用网络操作,这就是它崩溃的原因。您可以使用Kotlin Coroutines或使用Anko库的方法(kotlin正式支持以简化android中的内容)来避免这种情况。在这里,我只是给出了如何在Anko中进行异步调用的参考。
doAsync {
// Call all operation related to network or other ui blocking operations here.
uiThread {
// perform all ui related operation here
}
}
要像Kotlin Coroutines一样,你可以参考这个答案: -
答案 3 :(得分:0)
我找到了答案,基本上发生的事情是您无法在主线程上运行互联网连接,要覆盖,请将以下内容添加到用户正在执行网络操作的类中:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
参考文献 (https://www.educative.io/edpresso/how-to-fix-androidosnetworkonmainthreadexception-error)