我正在尝试从m[0].disable_tx();
内的网址获取数据,但在创建AsyncTask
的新实例时出现错误。
Java上的这样的东西
HttpUrlConnection
但我一直收到如下所示的错误。
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();
}
无法访问'':'受保护/ 受保护,并且包' /'在'HttpURLConnection'中无法创建抽象类的实例
我错过了什么吗?我试图创建一个扩展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)
}
}
的类对象并尝试实现HttpUrlConnection
方法,但我不能
提前致谢。
答案 0 :(得分:10)
以下是问题和答案的简化。
为什么这会失败?
val connection = HttpURLConnection()
val data = connection.inputStream.bufferedReader().readText()
// ... do something with "data"
有错误:
Kotlin:无法访问'':'HttpURLConnection'中的'受保护/ 受保护并打包 /'
这会失败,因为您正在构建一个不打算直接构造的类。它意味着由工厂创建,该工厂采用URL
类openConnection()
方法。这也不是原始问题中示例Java代码的直接端口。
Kotlin打开此连接并以字符串形式读取内容的最惯用方式是:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
val data = connection.inputStream.bufferedReader().readText()
此表单将在完成阅读文本或异常时自动关闭所有内容。如果你想做自定义阅读:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
connection.inputStream.bufferedReader().use { reader ->
// ... do something with the reader
}
注意: use()
扩展功能会打开并关闭阅读器并自动处理错误。
disconnect()
方法 disconnect
的文档说:
每个HttpURLConnection实例用于发出单个请求 但是与HTTP服务器的底层网络连接可能是 由其他实例透明共享。调用close()方法 在HttpURLConnection的InputStream或OutputStream上 请求后可以释放与此相关的网络资源 实例但对任何共享持久连接没有影响。 调用disconnect()方法可能会关闭底层套接字 如果此时持久连接处于空闲状态。
所以你决定是否要打电话。以下是调用disconnect的代码版本:
val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection
try {
val data = connection.inputStream.bufferedReader().readText()
// ... do something with "data"
} finally {
connection.disconnect()
}
答案 1 :(得分:2)
使用get
进行post
HTTPUrlConnection
请求的最简单方法是创建一个通用的帮助程序类,该类可以从应用程序中的任何位置调用以调用GET和POST请求方法,而不必一次又一次地编写相同的代码。
下面是辅助类object
(单例),您可以将其用于GET和POST请求的网络调用。
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()
}
}
使用上述对象类,您可以执行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()
除了使用线程,您还可以按照以下方式使用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()
}
}
}
您可以将asyncTask创建为Activity的内部类或单独的独立类。
现在可以通过NetworkAsyncCall
中的AsyncTask onCreate()
或要从中调用api的任何函数来调用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()
}
对于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()
}
您可以在github here中查看完整的代码。 要获得良好的解释,您可以选中此link。
使用NetworkAsyncCall作为独立的单独类的优点是,您不必再次编写AsyncTask代码,只需使用来自不同活动/功能的新对象调用同一AsyncTask NetworkAsyncCall
,从api获得响应后,必须实现一个onPostExecute()
上的回调将需要的侦听器接口,并将响应返回给必须使用该接口执行回调的活动。
答案 2 :(得分:0)
您可以适应您的代码;不要忘记用户可运行线程。
Thread(Runnable {
try {
val url = URL("www.android.com")
val con = url.openConnection() as HttpURLConnection
val datas = con.inputStream.bufferedReader().readText()
val json = JSONObject(datas)
val blockList = json.getJSONObject("blockList")
val warning = json.get("warnMessage").toString()
val keys = blockList.keys()
var permission = HashMap<String, Array<String?>>()
while (keys.hasNext()) {
val key = keys.next()
val kods = blockList.getJSONArray(key)
val permissonArray = arrayOfNulls<String>(kods.length())
for (i in permissonArray.indices) {
permissonArray[i] = kods.getString(i)
}
permission[key] = permissonArray;
}
} catch (ex: Exception) {
Log.d("Exception", ex.toString())
}
}).start()