Stack Exchange
A large amount of data posts into main thread android app
I have no idea how to solve problem when backend in synchronous way posts in main (UI) Thread a large amount of data (every 20 milliseconds a list of 1000 elements) and you can't change the code of backend. Post is going in such way:
class Server {
    private val mainThreadHandler = Handler(Looper.getMainLooper())
    private val processScope = CoroutineScope(Dispatchers.Default)

    private val instrumentNames = listOf(
        "EUR/USD_TOD",
        "GBP/USD_SPOT",
        "USD/JPY_TOM",
        "USD/CHF_SPOT",
        "USD/GBP_SPOT",
        "USD/CAD_TOM",
        "USD/RUB_TOM",
        "EUR/RUB_TOD",
        "CHF/RUB_TOM",
        "USD/AMD_SPOT",
        "EUR/GEL_SPOT",
        "UAH/RUB_SPOT",
        "USD/RUB_ON",
        "EUR/USD_TN",
    )

    fun subscribeToDeals(callback: (List<Deal>) -> Unit) {
        val currentTimeStamp = Date()

        processScope.launch {
            var deals = mutableListOf<Deal>()
            val dealsCount = (1_000_000L..1_001_000L).random()
            val dealsCountInPacket = 1_000
            var j = 0

            for (i in 0..dealsCount) {
                val deal = Deal(
                    id = i,
                    timeStamp = Date(currentTimeStamp.time + i),
                    instrumentName = instrumentNames.shuffled().first(),
                    price = getRandom(min = 60, max = 70),
                    amount = getRandom(min = 1_000_000, max = 50_000_000),
                    side = Deal.Side.values().toList().shuffled().first(),
                )
                deals.add(deal)

                j += 1

                if (j == dealsCountInPacket || i == dealsCount) {
                    j = 0
                    val delayValue = (0L..100L).random()
                    delay(delayValue)
                    val newDeals = deals

                    mainThreadHandler.post {
                        callback(newDeals)
                    }

                    deals = mutableListOf()
                }
            }
        }
    }

    private fun getRandom(min: Int, max: Int): Double {
        return min + Random.nextDouble() * (max - min)
    }

    data class Deal(
        val id: Long,
        val timeStamp: Date,
        val instrumentName: String,
        val price: Double,
        val amount: Double,
        val side: Side,
    ) {
        enum class Side {
            SELL, BUY
        }
    }
}

UI stars lagging
May be somebody has idea how to solve such examine tusk. How to correct implement invoke in repository callback method subscribeToDeals(callback) to not overload UI thread
solve using coroutine

After every thousand deals, you're posting to the main thread.  I have no idea what you're doing on that callback (not posted), but it's probably too much and your coroutine is sending more data than the UI thread can process.  That loop creating deals is going to run VERY quickly-  it doesn't do much.  So 1000 of them is going to take microseconds. Try upping it to 100K before sending a message and you'll probably see improvement.  Or even all of them at once.
Also, your code is... a bit odd.  I can get a random number of deals, you're creating random data for some test or process.  But why wait a random time before sending the message to the main thread?  And if you are, why so low an amount?  The average on that is 50ms, which is not very long.  But you aren't doing what you think you're doing (nothing is being sent every 20ms, it's being sent a random amount of time between immediately and 100ms).

It is just a task from interview. I think this task is useless too. In callback you have to save data into database just not to lose any. It is impossible to do this quickly and therefore it's blocking ui thread

Does the DB need to be written to on the main thread?  I wouldn't think so.  Swapping it to write on either this thread or a 3rd thread would be best.  If it must be written on the main thread, launch a coroutine on it and wait for that coroutine to finish before generating the next batch, so you don't overwhelm the thread with consecutive batches.

Of course I don't try to write DB on main thread.  I tried so: server.subscribeOnDeals  { CoroutineScope(Dispatchers.IO).launch {db.write(it)} } and ui starts lagging because server create 1000 coroutines in 1 second, and you can't change code of server
