@@ -185,36 +185,47 @@ class LogViewerActivity : AppCompatActivity() {
185
185
return @withContext
186
186
}
187
187
val stdout = BufferedReader (InputStreamReader (process!! .inputStream, StandardCharsets .UTF_8 ))
188
- var haveScrolled = false
189
- val start = System .nanoTime()
190
- var startPeriod = start
188
+
189
+ var posStart = 0
190
+ var timeLastNotify = System .nanoTime()
191
+ var priorModified = false
192
+ val bufferedLogLines = arrayListOf<LogLine >()
193
+ var timeout = 1000000000L / 2 // The timeout is initially small so that the view gets populated immediately.
194
+
191
195
while (true ) {
192
196
val line = stdout.readLine() ? : break
193
197
rawLogLines.append(line)
194
198
rawLogLines.append(' \n ' )
195
199
val logLine = parseLine(line)
200
+ if (logLine != null ) {
201
+ bufferedLogLines.add(logLine)
202
+ } else {
203
+ if (bufferedLogLines.isNotEmpty()) {
204
+ bufferedLogLines.last().msg + = " \n $line "
205
+ } else if (logLines.isNotEmpty()) {
206
+ logLines.last().msg + = " \n $line "
207
+ priorModified = true
208
+ }
209
+ }
210
+ val timeNow = System .nanoTime()
211
+ if ((timeNow - timeLastNotify) < timeout && stdout.ready())
212
+ continue
213
+ timeout = 1000000000L * 5 / 2 // Increase the timeout after the initial view has something in it.
214
+ timeLastNotify = timeNow
215
+
196
216
withContext(Dispatchers .Main .immediate) {
197
- if (logLine != null ) {
198
- recyclerView?.let {
199
- val shouldScroll = haveScrolled && ! it.canScrollVertically(1 )
200
- logLines.add(logLine)
201
- if (haveScrolled) logAdapter.notifyDataSetChanged()
202
- if (shouldScroll)
203
- it.scrollToPosition(logLines.size - 1 )
204
- }
205
- } else {
206
- logLines.lastOrNull()?.msg + = " \n $line "
207
- if (haveScrolled) logAdapter.notifyDataSetChanged()
217
+ val isScrolledToBottomAlready = recyclerView?.canScrollVertically(1 ) == false
218
+ if (priorModified) {
219
+ logAdapter.notifyItemChanged(posStart - 1 )
220
+ priorModified = false
208
221
}
209
- if (! haveScrolled) {
210
- val end = System .nanoTime()
211
- val scroll = (end - start) > 1000000000L * 2.5 || ! stdout.ready()
212
- if (logLines.isNotEmpty() && (scroll || (end - startPeriod) > 1000000000L / 4 )) {
213
- logAdapter.notifyDataSetChanged()
214
- recyclerView?.scrollToPosition(logLines.size - 1 )
215
- startPeriod = end
216
- }
217
- if (scroll) haveScrolled = true
222
+ logLines.addAll(bufferedLogLines)
223
+ bufferedLogLines.clear()
224
+ logAdapter.notifyItemRangeInserted(posStart, logLines.size - posStart)
225
+ posStart = logLines.size
226
+
227
+ if (isScrolledToBottomAlready) {
228
+ recyclerView?.scrollToPosition(logLines.size - 1 )
218
229
}
219
230
}
220
231
}
0 commit comments