AsyncTask in Android with Kotlin

前端 未结 10 1512
离开以前
离开以前 2020-12-13 12:31

How to make an API call in Android with Kotlin?

I have heard of Anko . But I want to use methods provided by Kotlin like in Android we have Asynctask for background

相关标签:
10条回答
  • 2020-12-13 12:54

    I spent a full day trying to figure how to get back the result produced by an Async Task : co-routines was my solution !!!

    First, create your AsyncTask Object ... Do not forget to use corrects parameter type instead all Any

    @SuppressLint("StaticFieldLeak")
    class AsyncTaskExample(private var activity: MainActivity?) : AsyncTask<Any, Int, Any?>() {
    
        override fun onPreExecute() {
            super.onPreExecute()
            // do pre stuff such show progress bar
        }
    
        override fun doInBackground(vararg req: Any?): Any? {
    
            // here comes your code that will produce the desired result
            return result 
    
        }
    
        // it will update your progressbar
        override fun onProgressUpdate(vararg values: Int?) {
            super.onProgressUpdate(*values)
    
        }
    
    
        override fun onPostExecute(result: Any?) {
            super.onPostExecute(result)
    
            // do what needed on pos execute, like to hide progress bar
            return
        }
    
    }
    

    and Then, call it ( in this case, from main activity )

    var task = AsyncTaskExample(this)
    var req = { "some data object or whatever" }
    
    GlobalScope.launch( context = Dispatchers.Main){
    
       task?.execute(req)
    }
    
    GlobalScope.launch( context = Dispatchers.Main){
    
       println( "Thats the result produced by doInBackgorund: " +  task?.get().toString() )
    }
    
    0 讨论(0)
  • 2020-12-13 12:55

    Here is an example that will also allow you to update any UI or progress displayed to the user.

    Async Class

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

    Simple Usage

    doAsync {
        // do work here ...
    
        myView.post({
            // update UI of myView ...
        })
    }
    
    0 讨论(0)
  • 2020-12-13 13:00

    if in the case you want to do it without using Anko and the correct way is to use the following way

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

    and the way to execute it is as follows

    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 讨论(0)
  • 2020-12-13 13:04

    You can get a similar syntax to Anko's fairly easy. If you just wan't the background task you can do something like

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

    And use it like

    doAsync {
        yourTask()
    }.execute()
    
    0 讨论(0)
  • 2020-12-13 13:06
    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)
        }
    }
    

    link - Github Irontec

    0 讨论(0)
  • 2020-12-13 13:07

    AsyncTask is an Android API, not a language feature that is provided by Java nor Kotlin. You can just use them like this if you want:

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

    Anko's doAsync is not really 'provided' by Kotlin, since Anko is a library that uses language features from Kotlin to simplify long codes. Check here:

    • https://github.com/Kotlin/anko/blob/d5a526512b48c5cd2e3b8f6ff14b153c2337aa22/anko/library/static/commons/src/Async.kt

    If you use Anko your code will be similar to this:

    doAsync {
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题