axi*_*tjz 3 android httpurlconnection kotlin
我试图从内部的网址获取数据,AsyncTask但在创建新实例时出现错误HttpUrlConnection.
在Java上有这样的东西
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
finally {
urlConnection.disconnect();
}
Run Code Online (Sandbox Code Playgroud)
但我不断收到下面显示的错误.
class GetWeatherTask : AsyncTast<Void, Void, Void>() {
override fun doInBackground(vararg params: Void?): Void? {
val httpClient = HttpURLConnection();
return null
}
override fun onPreExecute() {
super.onPreExecute()
}
override fun onPostExecute(result: Void?) {
super.onPostExecute(result)
}
}
Run Code Online (Sandbox Code Playgroud)
无法访问'':它是'受保护/ 受保护,而 '/ httpURLConnection'中的包 /'无法创建抽象类的实例
我错过了什么吗?我试图创建一个扩展的类对象HttpUrlConnection并尝试实现该init方法,但我不能
提前致谢.
Jay*_*ard 12
这是问题和答案的简化.
为什么这会失败?
val connection = HttpURLConnection()
val data = connection.inputStream.bufferedReader().readText()
// ... do something with "data"
Run Code Online (Sandbox Code Playgroud)
有错误:
Kotlin:无法访问'':'HttpURLConnection'中的'受保护/ 受保护和包 /'
这会失败,因为您正在构建一个不打算直接构造的类.它意味着由工厂创建,这是URL类openConnection()方法.这也不是原始问题中示例Java代码的直接端口.
在Kotlin中打开此连接并以字符串形式读取内容的最惯用方式是:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
val data = connection.inputStream.bufferedReader().readText()
Run Code Online (Sandbox Code Playgroud)
完成阅读文本或异常后,此表单将自动关闭所有内容.如果你想做自定义阅读:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
connection.inputStream.bufferedReader().use { reader ->
// ... do something with the reader
}
Run Code Online (Sandbox Code Playgroud)
注: 该use()扩展功能将打开和关闭阅读器和手柄自动关闭上的错误.
disconnect()方法文档disconnect说:
每个HttpURLConnection实例用于发出单个请求,但是与HTTP服务器的基础网络连接可以由其他实例透明地共享.在请求之后调用HttpURLConnection的InputStream或OutputStream上的close()方法可以释放与此实例关联的网络资源,但不会影响任何共享持久连接.如果此时持久连接处于空闲状态,则调用disconnect()方法可能会关闭底层套接字.
所以你决定是否要打电话.以下是调用disconnect的代码版本:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
try {
val data = connection.inputStream.bufferedReader().use { it.readText() }
// ... do something with "data"
} finally {
connection.disconnect()
}
Run Code Online (Sandbox Code Playgroud)
get post执行请求的最简单方法HTTPUrlConnection是创建一个通用帮助程序类,可以从应用程序中的任何位置调用该类来调用 GET 和 POST 请求方法,而无需一次又一次编写相同的代码。
下面是object可用于 GET 和 POST 请求的网络调用的帮助程序 (Singleton) 类。
package com.dewari.ajay.androidnetworkcommunication.network
import org.json.JSONObject
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLEncoder
import javax.net.ssl.HttpsURLConnection
object RequestHandler {
const val GET : String = "GET"
const val POST : String = "POST"
@Throws(IOException::class)
fun requestPOST(r_url: String?, postDataParams: JSONObject): String? {
val url = URL(r_url)
val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
conn.readTimeout = 3000
conn.connectTimeout = 3000
conn.requestMethod = POST
conn.doInput = true
conn.doOutput = true
val os: OutputStream = conn.outputStream
val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8"))
writer.write(encodeParams(postDataParams))
writer.flush()
writer.close()
os.close()
val responseCode: Int = conn.responseCode // To Check for 200
if (responseCode == HttpsURLConnection.HTTP_OK) {
val `in` = BufferedReader(InputStreamReader(conn.inputStream))
val sb = StringBuffer("")
var line: String? = ""
while (`in`.readLine().also { line = it } != null) {
sb.append(line)
break
}
`in`.close()
return sb.toString()
}
return null
}
@Throws(IOException::class)
fun requestGET(url: String?): String? {
val obj = URL(url)
val con = obj.openConnection() as HttpURLConnection
con.requestMethod = GET
val responseCode = con.responseCode
println("Response Code :: $responseCode")
return if (responseCode == HttpURLConnection.HTTP_OK) { // connection ok
val `in` =
BufferedReader(InputStreamReader(con.inputStream))
var inputLine: String?
val response = StringBuffer()
while (`in`.readLine().also { inputLine = it } != null) {
response.append(inputLine)
}
`in`.close()
response.toString()
} else {
""
}
}
@Throws(IOException::class)
private fun encodeParams(params: JSONObject): String? {
val result = StringBuilder()
var first = true
val itr = params.keys()
while (itr.hasNext()) {
val key = itr.next()
val value = params[key]
if (first) first = false else result.append("&")
result.append(URLEncoder.encode(key, "UTF-8"))
result.append("=")
result.append(URLEncoder.encode(value.toString(), "UTF-8"))
}
return result.toString()
}
}
Run Code Online (Sandbox Code Playgroud)
使用上面的对象类,您可以执行 GET 和 POST 请求,如下所示:
//As this is network call it should be done in a separate thread
Thread(Runnable {
RequestHandler.requestGET(url)
RequestHandler.requestPOST(url, postJSONObject)
}).start()
Run Code Online (Sandbox Code Playgroud)
除了使用线程之外,您还可以使用 AsyncTask,如下所示:
class NetworkAsyncCall(private val context: Context, private val url: String, private val requestType:
String, private val postJSONObject: JSONObject = JSONObject()
) : AsyncTask<String?, String?, String?>() {
override fun doInBackground(vararg p0: String?): String? {
return when (requestType) {
RequestHandler.GET -> RequestHandler.requestGET(url)
RequestHandler.GET -> RequestHandler.requestPOST(url, postJSONObject)
else -> ""
}
}
override fun onPostExecute(s: String?) {
if (s != null) {
Toast.makeText(context, s, Toast.LENGTH_LONG).show()
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将 asyncTask 创建为 Activity 的内部类或单独的独立类。
NetworkAsyncCall现在,要通过您的AsyncTaskonCreate()或任何您想要调用 api 的函数中的AsyncTask 调用 newtwork,您可以编写:
注意:上述网址不起作用,因此您必须将其替换为您自己的网址。
override fun onCreate(savedInstanceState: Bundle?) {
setContentView(R.layout.activity_main)
// Change the url with your own GET URL request
val urlGET = "http://my-json-feed"
//GET Request
NetworkAsyncCall(this@MainActivity, urlGET, RequestHandler.GET).execute();
// POST Request
// doPost()
}
Run Code Online (Sandbox Code Playgroud)
对于 POST 请求,您可以致电:
private fun doPost() {
// Change the url with your own POST URL request
val urlPOST = "http://my-json-feed"
val postDataParams = JSONObject()
postDataParams.put("name", "Ajay")
postDataParams.put("email", "aj****ri@gmail.com")
postDataParams.put("phone", "+91 78******25")
NetworkAsyncCall(this@MainActivity, urlPOST, RequestHandler.POST, postDataParams).execute()
}
Run Code Online (Sandbox Code Playgroud)
你可以在这里查看 github 中的完整代码。要获得更好的解释,您可以查看此链接。
使用 NetworkAsyncCall 作为单独的独立类的优点是您不必再次编写 AsyncTask 代码,只需使用NetworkAsyncCall来自不同活动/函数的新对象调用相同的 AsyncTask 即可,但是这样您就必须实现一个侦听器接口从 api 获取响应后需要进行回调onPostExecute(),并将响应返回到必须使用该接口执行回调的活动。
| 归档时间: |
|
| 查看次数: |
11249 次 |
| 最近记录: |