Android: приложение может выполнять слишком много работы в основном потоке - PullRequest
0 голосов
/ 28 февраля 2019

Таким образом, я получаю эту ошибку даже при отладке на подключенном устройстве.

Мое приложение считывает файл JSON через HTTP-соединение, сохраняет его и уведомляет всех наблюдателей о получении новых данных.Одним из наблюдателей является графопостроитель, использующий библиотеку grapView Lib.

. Когда я искал некоторые решения, я в итоге реализовал JSON Parser как AsyncTask.

Но та же ошибка по-прежнему возникает.

Мой вопрос сейчас таков: что еще я могу сделать, чтобы основной поток заблокирован?

Main:

class MainScreen : AppCompatActivity() {

//define variables
private lateinit var start: Button

private lateinit var graphView: GraphView

private lateinit var engineTempText: TextView
private lateinit var speedText: TextView

private val timer = Timer("schedule", true)

private var started = false

//find GUI fields/buttons
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main_screen)

    start = findViewById(R.id.startButton)

    graphView = findViewById(R.id.graphView)

    engineTempText = findViewById(R.id.engineTempText)
    speedText = findViewById(R.id.speedText)

    //Register Observers at DataWarehouse
    val engineTempObserver = EngineTempObserver(engineTempText)
    val speedObserver = SpeedObserver(speedText)
    val plotter = Plotter(graphView)

    //Wait till Button is pressed to start
    start.setOnClickListener(View.OnClickListener {

        //end
        if (started) {
            timer.cancel()
            timer.purge()
            started = false
        }

        //start
        else {
            started = true

            val timer = Timer("schedule", true)
            timer.scheduleAtFixedRate(500,500) {

                Handler(Looper.getMainLooper()).post {
                    //Start
                    start()
                }
            }
        }

    })
}

//start monitoring
private fun start() {
    val jsonParser = JsonParser()
    jsonParser.execute()
}

}

JSON Parser:

class JsonParser : AsyncTask<Void, Void, JsonObject>() {

//connect to URL get Json File Data
override fun doInBackground(vararg params: Void): JsonObject {

    val response = URL("https://api.myjson.com/bins/14oooa").readText()
    //http://10.0.2.2:80/test.json

    //create Parser
    val parser = Parser()
    val stringBuilder = StringBuilder(response)

    //Read Json File + get Data
    val jsonObject: JsonObject = parser.parse(stringBuilder) as JsonObject

    return jsonObject

}

//Parse Json File extract Data and store them in DataWarehouse
override fun onPostExecute(jsonObject: JsonObject) {

    //Arrays to Store Coordinates saved in Cone class
    val blueConeArray = arrayListOf<Cone>()
    val yellowConeArray = arrayListOf<Cone>()


    //Get Cones from JsonObject
    val blueCoordinates: JsonArray<JsonObject>? = jsonObject.array("BlueCoordinates")
    val yellowCoordinates: JsonArray<JsonObject>? = jsonObject.array("YellowCoordinates")

    //Store Blue Cones
    for (coordinate in blueCoordinates!!) {
        val x_blue = coordinate.double("x")
        val y_blue = coordinate.double("y")

        val blueCone = BlueCone(x_blue!!, y_blue!!)
        blueConeArray.add(blueCone)
    }

    //Store Yellow Cones
    for (coordinate in yellowCoordinates!!) {
        val x_yellow = coordinate.double("x")
        val y_yellow = coordinate.double("y")
        val yellowCone = YellowCone(x_yellow!!, y_yellow!!)
        yellowConeArray.add(yellowCone)
    }

    //Store everything in Data Warehouse
    DataWarehouse.setValues(
        newEngineTemp = jsonObject.string("engineTemp"),
        newSpeed = jsonObject.string("speed"),
        newBlueCones = blueConeArray,
        newYellowCones = yellowConeArray
    )
    blueConeArray.clear()
    yellowConeArray.clear()

}

}

Плоттер:

class Plotter(graphView: GraphView) : Observer {

private var graphView = graphView

private lateinit var sortedBlueCones: MutableList<Cone>
private lateinit var sortedYellowCones: MutableList<Cone>

private var blueConeArrayList = ArrayList<DataPoint>()
private var yellowConeArrayList = ArrayList<DataPoint>()

private var blueLines = LineGraphSeries<DataPoint>()
private var yellowLines = LineGraphSeries<DataPoint>()

private var blueIterator = 0
private var yellowIterator = 0

init {

    //First Values so resetData works
    yellowLines.appendData((DataPoint(0.toDouble(), 0.toDouble())), true, 1000)
    blueLines.appendData((DataPoint(0.toDouble(), 0.toDouble())), true, 1000)

    register()
}

//Register at Data Warehouse
override fun register() {
    DataWarehouse.registerObserver(this)
}

//Get new Cones from Data Warehouse and sort them by X Values
override fun update() {

    sortedBlueCones = DataWarehouse.getBlueCones().sortedWith(compareBy({ it.xCoordinate })) as MutableList<Cone>
    sortedYellowCones = DataWarehouse.getYellowCones().sortedWith(compareBy({ it.xCoordinate })) as MutableList<Cone>

    draw()
}

//Draw Line Graph and Point Graph
private fun draw() {

        //Blue Cones
        for (i in sortedBlueCones) {

            var x: Double = sortedBlueCones.get(blueIterator).xCoordinate
            var y: Double = sortedBlueCones.get(blueIterator).yCoordinate

            var dataPoint = DataPoint(x, y)
            blueConeArrayList.add(dataPoint)
            val blueConeArray = arrayOfNulls<DataPoint>(blueConeArrayList.size)
            blueConeArrayList.toArray(blueConeArray)

            blueLines.resetData(blueConeArray)

            blueIterator++
        }


        //Yellow Cones
        for (i in sortedYellowCones) {
            var x: Double = sortedYellowCones.get(yellowIterator).xCoordinate
            var y: Double = sortedYellowCones.get(yellowIterator).yCoordinate

            var dataPoint = DataPoint(x, y)
            yellowConeArrayList.add(dataPoint)
            val yellowConeArray = arrayOfNulls<DataPoint>(yellowConeArrayList.size)
            yellowConeArrayList.toArray(yellowConeArray)

            yellowLines.resetData(yellowConeArray)

            yellowIterator++
        }

    //Set Values of Lines
    blueLines.setColor(Color.BLUE)
    blueLines.setDrawDataPoints(true)
    blueLines.setDataPointsRadius(10.toFloat())

    yellowLines.setColor(Color.YELLOW)
    yellowLines.setDrawDataPoints(true)
    yellowLines.setDataPointsRadius(10.toFloat())

    //Draw
    graphView.addSeries(blueLines)
    graphView.addSeries(yellowLines)

    blueIterator = 0
    yellowIterator = 0

    blueConeArrayList.clear()
    yellowConeArrayList.clear()
}

}

1 Ответ

0 голосов
/ 28 февраля 2019

onPostExecute(jsonObject: JsonObject) вызывается в главном потоке, похоже, вы там много работаете (для циклов и сохранения БД).Попробуйте сделать это в фоновом режиме, а затем верните только то, что нужно сделать в основном потоке.

Кроме этих ошибок (которые на самом деле являются предупреждениями) можно в основном игнорировать, особенно если вы работаете на старом телефоне или эмуляторе.Если это на самом деле не вызывает видимых задержек, вы должны быть в порядке, если время задержки не является значительным и постоянно происходит.

...