web-dev-qa-db-fra.com

AsyncTask dans Android avec Kotlin

Comment faire un appel API dans Android avec Kotlin?

J'ai entendu parler de Anko . Mais je veux utiliser les méthodes fournies par Kotlin, comme dans Android, nous avons Asynctask pour les opérations en arrière-plan.

18
Rakesh Gujari

AsyncTask est un Android API, pas une fonctionnalité language fournie par Java ni Kotlin. Vous pouvez simplement les utiliser comme ceci si vous voulez:

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)
        // ...
    }
}

La variable doAsync d'Anko n'est pas vraiment "fournie" par Kotlin, car Anko est une bibliothèque qui utilise les fonctionnalités de langage de Kotlin pour simplifier les codes longs. Vérifier ici:

Si vous utilisez Anko, votre code sera similaire à ceci:

doAsync {
    // ...
}
33
shiftpsh

Vous pouvez obtenir une syntaxe similaire à celle d'Anko, assez facile. Si vous ne voulez pas que la tâche de fond, vous pouvez faire quelque chose comme 

class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void?): Void? {
        handler()
        return null
    }
}

Et l'utiliser comme 

doAsync {
    yourTask()
}.execute()
19
Algar

Voici un exemple qui vous permettra également de mettre à jour toute interface utilisateur ou toute progression affichée à l'utilisateur.

Classe Async

class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
    init {
        execute()
    }

    override fun doInBackground(vararg params: Void?): Void? {
        handler()
        return null
    }
}

Utilisation simple

doAsync {
    // do work here ...

    myView.post({
        // update UI of myView ...
    })
}
6
quemeful
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)
    }
}

lien - Github Irontec

4
Gopi.cs

J'utilise toujours ce formulaire:

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
    }
}

Vous l'invoquez de la manière suivante:

loadingProducts = object : LoadingProducts() {
        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)

            Log.e("Result", result)
        }
    }

loadingProducts.execute()

J'utilise open pour pouvoir appeler la méthode onPostExecute comme résultat.

1

si dans le cas où vous voulez le faire sans utiliser Anko et la bonne façon est d'utiliser la manière suivante

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}
}

et la façon de l'exécuter est la suivante

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)
0