AsyncTask в Android с Котлином
Как сделать вызов API в Android с помощью Kotlin?
Я слышал о Анко . Но я хочу использовать методы, предоставляемые Kotlin, как в Android, у нас есть Asynctask для фоновых операций.
7 ответов
AsyncTask
является Android API, а не языка это предусмотрено Java nor Kotlin. Вы можете просто использовать их так, если хотите:
class someTask() : AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg params: Void?): String? {
// ...
}
override fun onPreExecute() {
super.onPreExecute()
// ...
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
// ...
}
}
Анко!--3--> на самом деле не "предоставляется" Котлином, так как Anko-это библиотека, которая использует языковые функции из Котлина для упрощения длинных кодов. Проверять здесь:
если вы используете Anko, ваш код будет похож на это:
doAsync {
// ...
}
вы можете получить аналогичный синтаксис для Anko довольно легко. Если вы просто не хотите фоновую задачу, вы можете сделать что-то вроде
class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void?): Void? {
handler()
return null
}
}
и использовать его как
doAsync {
yourTask()
}.execute()
package com.irontec.kotlintest
import android.os.AsyncTask
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.io.BufferedInputStream
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GetWeatherTask(this.text).execute()
}
class GetWeatherTask(textView: TextView) : AsyncTask<Unit, Unit, String>() {
val innerTextView: TextView? = textView
override fun doInBackground(vararg params: Unit?): String? {
val url = URL("https://raw.githubusercontent.com/irontec/android-kotlin-samples/master/common-data/bilbao.json")
val httpClient = url.openConnection() as HttpURLConnection
if (httpClient.responseCode == HttpURLConnection.HTTP_OK) {
try {
val stream = BufferedInputStream(httpClient.inputStream)
val data: String = readStream(inputStream = stream)
return data
} catch (e: Exception) {
e.printStackTrace()
} finally {
httpClient.disconnect()
}
} else {
println("ERROR ${httpClient.responseCode}")
}
return null
}
fun readStream(inputStream: BufferedInputStream): String {
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
val stringBuilder = StringBuilder()
bufferedReader.forEachLine { stringBuilder.append(it) }
return stringBuilder.toString()
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
innerTextView?.text = JSONObject(result).toString()
/**
* ... Work with the weather data
*/
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == R.id.action_settings) {
return true
}
return super.onOptionsItemSelected(item)
}
}
ссылка - Github Irontec
вот пример, который также позволит вам обновить любой пользовательский интерфейс или прогресс, отображаемый пользователю.
Асинхронный Класс
class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
init {
execute()
}
override fun doInBackground(vararg params: Void?): Void? {
handler()
return null
}
}
Простота Использования
doAsync {
// do work here ...
myView.post({
// update UI of myView ...
})
}
Я всегда использую эту форму:
open class LoadingProducts : AsyncTask<Void, Void, String>() {
private var name = ""
override fun doInBackground(vararg p0: Void?): String {
for (i in 1..100000000) {
if (i == 100000000) {
name = "Hello World"
}
}
return name
}
}
вы вызываете его следующим образом:
loadingProducts = object : LoadingProducts() {
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
Log.e("Result", result)
}
}
loadingProducts.execute()
Я использую open, чтобы я мог вызвать onPostExecute
метод для результата.
Если в случае, если вы хотите сделать это без использования Anko, и правильный способ-использовать следующий способ
open class PromotionAsyncTask : AsyncTask<JsonArray, Void, MutableList<String>>() {
private lateinit var out: FileOutputStream
private lateinit var bitmap: Bitmap
private lateinit var directory: File
private var listPromotion: MutableList<String> = mutableListOf()
override fun doInBackground(vararg params: JsonArray?): MutableList<String> {
directory = Environment.getExternalStoragePublicDirectory("Tambo")
if (!directory.exists()) {
directory.mkdirs()
}
for (x in listFilesPromotion(params[0]!!)) {
bitmap = BitmapFactory.decodeStream(URL(x.url).content as InputStream)
out = FileOutputStream(File(directory, "${x.name}"))
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
out.flush()
out.close()
listPromotion.add(File(directory, "${x.name}").toString())
}
return listPromotion
}
private fun listFilesPromotion(jsonArray: JsonArray): MutableList<Promotion> {
var listString = mutableListOf<Promotion>()
for (x in jsonArray) {
listString.add(Promotion(x.asJsonObject.get("photo")
.asString.replace("files/promos/", "")
, "https://tambomas.pe/${x.asJsonObject.get("photo").asString}"))
}
return listString}
}
и способ его выполнения выглядит следующим образом
promotionAsyncTask = object : PromotionAsyncTask() {
override fun onPostExecute(result: MutableList<String>?) {
super.onPostExecute(result)
listFile = result!!
contentLayout.visibility = View.VISIBLE
progressLottie.visibility = View.GONE
}
}
promotionAsyncTask.execute(response!!.body()!!.asJsonObject.get("promos").asJsonArray)
private fun updateUI(account: GoogleSignInAccount?) {
if (account != null) {
try {
AsyncTaskExample().execute()
} catch (e: Exception) {
}
}
}
inner class AsyncTaskExample : AsyncTask<String, String, String>() {
override fun onPreExecute() {
super.onPreExecute()
}
override fun doInBackground(vararg p0: String?): String {
var Result: String = "";
try {
googleToken = GoogleAuthUtil.getToken(activity, accountVal, "oauth2:https://www.googleapis.com/auth/userinfo.profile")
signOut()
} catch (e: Exception) {
signOut()
}
signOut()
return Result
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
socialPrsenter.setDataToHitApiGoogleLogin(googleToken ?: "")
}
}