我从here获得了这种方法,并且效果很好:
@Throws(IOException::class)
fun readTextFromUri(ctx: Context, uri: Uri): String {
val stringBuilder = StringBuilder()
ctx.contentResolver.openInputStream(uri)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
stringBuilder.append("$line\n")
line = reader.readLine()
}
}
}
return stringBuilder.toString()
}
然后将其转换为使用Observable返回每一行的方法:
fun getUriAsStringObservable(ctx: Context, uri: Uri): Observable<String> {
return Observable.create {
try {
ctx.contentResolver.openInputStream(uri)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
it.onNext(line)
line = reader.readLine()
}
it.onComplete()
}
}
} catch (e: IOException) {
it.onError(e)
}
}
}
但是它没有按照我的预期工作,订阅了之后什么也没打印:
getUriAsStringObservable(this, uri)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext {
print("Next: $it")
}
.doOnError {
print("Error: $it")
}
.doOnComplete {
print("completed")
}
.subscribe()
我怎么了?
答案 0 :(得分:0)
我找到了解决问题的三种方法:
1)发射每一项后,使用Thread.sleep(1)
。
2)使用具有非deamon
线程link的自定义调度程序。
3)将Flowable与BackpressureStrategy.BUFFER
一起使用,而不是Observable(最佳方式)。
Flowable.create({
try {
ctx.contentResolver.openInputStream(uri)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
it.onNext(line)
line = reader.readLine()
}
it.onComplete()
}
}
} catch (e: IOException) {
it.onError(e)
}
}, BackpressureStrategy.BUFFER)
谢谢Javid