Android:java.lang.IllegalThreadStateException

时间:2019-03-03 16:55:11

标签: android multithreading kotlin android-graphview

因此,我的应用程序从JSON文件读取数据,并将其存储在名为“ DataWarehouse”的类中,并通知所有观察者获取新数据。

观察者之一是使用graphView lib的绘图仪。画线。由于新坐标的排序和计算需要花费大量时间,因此我在线程“ CalcCoordinatesThread”中进行了此操作。 但是我收到一条错误消息,并且该线程甚至没有运行。

这是我第一次在Android中使用Threads,我真的不知道自己在做什么错,我已经花了将近一天的时间。非常感谢您的帮助。

谢谢。

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tobias.infinity_racing_driverless, PID: 13911
java.lang.IllegalThreadStateException
    at java.lang.Thread.start(Thread.java:724)
    at com.example.tobias.infinity_racing_driverless.PlotterRunnable.start(PlotterRunnable.kt:49)
    at com.example.tobias.infinity_racing_driverless.PlotterRunnable.update(PlotterRunnable.kt:37)
    at com.example.tobias.infinity_racing_driverless.DataWarehouse.notifyObservers(DataWarehouse.kt:34)
    at com.example.tobias.infinity_racing_driverless.DataWarehouse.setValues(DataWarehouse.kt:54)
    at com.example.tobias.infinity_racing_driverless.JsonParser.onPostExecute(JsonParser.kt:58)
    at com.example.tobias.infinity_racing_driverless.JsonParser.onPostExecute(JsonParser.kt:12)
    at android.os.AsyncTask.finish(AsyncTask.java:695)
    at android.os.AsyncTask.-wrap1(Unknown Source:0)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

CalcCoordinatesThread:

class CalcCoordinatesThread(private var uiHandler: MainScreen.UiHandler) : HandlerThread("CalcCoordinatesThread") {

private var handler: Handler? = null

//calc blue Cones
private fun calcBlueLines(blueCones: ArrayList<Cone>): LineGraphSeries<DataPoint> {

    var blueLines = LineGraphSeries<DataPoint>()
    var blueConeArrayList = ArrayList<DataPoint>()
    var blueIterator = 0

    val sortedBlueCones = blueCones.sortedWith(compareBy({ it.xCoordinate })) as MutableList<Cone>


    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++
    }
    blueConeArrayList.clear()

    return blueLines
}

//calc yellow Cones
private fun calcYellowLines(yellowCones: ArrayList<Cone>): LineGraphSeries<DataPoint> {

    var yellowLines = LineGraphSeries<DataPoint>()
    var yellowConeArrayList = ArrayList<DataPoint>()
    var yellowIterator = 0

    val sortedYellowCones = yellowCones.sortedWith(compareBy({ it.xCoordinate })) as MutableList<Cone>


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

    yellowConeArrayList.clear()
    return yellowLines
}

//Handler gets and sends new Messages
private fun getHandler(looper: Looper): Handler {
    return object : Handler(looper) {
        override fun handleMessage(msg: Message?) {
            super.handleMessage(msg)

            //get Message with coordinates of Cones
            val coordinates = msg?.obj as Array<ArrayList<Cone>>

            //calc Lines
            var blueLines = calcBlueLines(coordinates[0])
            var yellowLines = calcYellowLines(coordinates[1])

            //Send Message of new LineSeries
            val lineMessage = Message()
            lineMessage.obj = arrayOf<LineGraphSeries<DataPoint>>(blueLines, yellowLines)
            uiHandler.sendMessage(lineMessage)

        }
    }
}

//Handler gets Message with new coordinates of Cones
fun sendCoordinates(coordinates: Array<ArrayList<Cone>>) {
    val message = Message()
    message.obj = coordinates
    handler?.sendMessage(message)
}

//start looper
override fun onLooperPrepared() {
    super.onLooperPrepared()
    handler = getHandler(looper)
}

}

绘图仪:

class PlotterRunnable(private var calcCoordinatesThread: CalcCoordinatesThread) : Observer, Runnable {

private var thread: Thread = Thread(this)

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

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() {

    if(!thread.isAlive)
    {
        start()
        run()
    }
}

override fun run() {

    val coordinateArray = arrayOf<ArrayList<Cone>>(DataWarehouse.blueConesList, DataWarehouse.yellowConesList)
    calcCoordinatesThread.sendCoordinates(coordinateArray)
}

fun start(){
    thread.start()
}

}

主要:

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

private lateinit var plotter: PlotterRunnable
private lateinit var uiHandler: UiHandler
private lateinit var calcCoordinatesThread: CalcCoordinatesThread
private lateinit var engineTempObserver: EngineTempObserver
private lateinit var speedObserver: SpeedObserver

//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
    engineTempObserver = EngineTempObserver(engineTempText)
    speedObserver = SpeedObserver(speedText)

    uiHandler = UiHandler(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
            start()
        }
    })
}

//start monitoring
private fun start() {

    calcCoordinatesThread = CalcCoordinatesThread(uiHandler)
    plotter = PlotterRunnable(calcCoordinatesThread)

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

        //Start
        if (started) {
            val jsonParser = JsonParser()
            jsonParser.execute()
        }

    }
}

override fun onDestroy() {
    super.onDestroy()
    calcCoordinatesThread.quit()

}

class UiHandler(var graphView: GraphView) : Handler() {

    override fun handleMessage(msg: Message?) {
        super.handleMessage(msg)
        var lines = msg?.obj as Array<LineGraphSeries<DataPoint>>

        var blueLine = lines[0]
        var yellowLine = lines[1]

        graphView.addSeries(blueLine)
        graphView.addSeries(yellowLine)
    }
}

}

0 个答案:

没有答案