Search code examples
androidkotlinoutputprocessbuilder

How to get per line process output in an android app?


I'm using this code:

var reader: Int = 0
val buffer = CharArray(4096)
var output = StringBuilder()
val process = processBuilder.start()
var inputStream =  BufferedReader(InputStreamReader(process.getInputStream()));

while ({ reader = inputStream.read(buffer); reader }() > 0) {
       output.append(buffer, 0, reader)
       println("Debug: " + output.toString())
      }
       inputStream.close()
       process.waitFor()

It works fine but I have 2 issues that make it not to meet my needs:

1) It doesn't retrieve each line in real time. It buffers some lines from the actual output and it shows them on every loop.

2) The result is appended. I only need the actual and single line of the output on every iteration.


Solution

  • Pretty elegant Kotlin-ish solution:

    var output: String = ""
    val process = processBuilder.start()                 
    val inputStream =  BufferedReader(InputStreamReader(process.getInputStream()))
    while ( inputStream.readLine()?.also { output = it } != null) {
      println("Debug: " + output)
    }
    inputStream.close()
    process.waitFor()
    

    The while statement is equivalent to Java's:

    while ( (output = inputStream.readLine()) != null) {
     println("Debug: " + output)
    }
    

    In Kotlin, you cant assign variables inside statements but using the also chain, you can include extra code to be executed at the same time. The Elvis operator (?) after the readLine allows "it" to become null in order for the latest check to be performed. This is necessairy to avoid crashes.