协程读取文件
协程读取文件
package com.linkdom.readbook.learning
import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.InputStreamReader
@Composable
fun Test() {
val context = LocalContext.current
val text = remember { mutableStateOf("") }
val coroutineScope = rememberCoroutineScope()
// val scrollState = rememberScrollState()
Column (
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
){
Button(onClick = {
coroutineScope.launch {
readFile(context){
text.value = text.value + "\n" + it
}
}
}) {
Text("读取文件")
}
Text(
text = text.value,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(10.dp)
)
}
}
@OptIn(DelicateCoroutinesApi::class)
private fun readFile(
context: Context,
onRead: (String) -> Unit
) {
GlobalScope.launch(Dispatchers.IO) {
// println("${Thread.currentThread().name}执行文件读取任务。\n")
val inputStream = context.assets.open("第一章:刹车时代.txt")
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
var line: String? = bufferedReader.readLine()
while (line != null) {
onRead(line)
line = bufferedReader.readLine()
}
}
}
@Preview(showBackground = true)
@Composable
fun Test4() {
Test()
}
注:就这一点困扰了自己很多天,还是自己不够理解协程加载文件的原理,还有读取文件目录的资源,还有诸如让text可以滑动等等功能。。。
对于Compose协程加载文件
@Composable
fun Test() {
val context = LocalContext.current
val text = remember { mutableStateOf("") }
val coroutineScope = rememberCoroutineScope()
Column (
...
){
Button(onClick = {
coroutineScope.launch {
readFile(context){
text.value = text.value + "\n" + it
}
}
}) {
Text("读取文件")
}
Text(
text = text.value,
...
)
}
}
读取本地资源文件
val inputStream = context.assets.open("第一章:刹车时代.txt")
这个context.assets的路径就是要将tmp.txt
文件移动到app/src/main/assets
文件夹下(如果没有该文件夹,请创建一个)(问GPT才知道的)。
可上下滑动的text
Text(
text = text.value,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(10.dp)
)
就是加一个modifier中的.verticalScroll(rememberScrollState())
即可;
可参考官方文档:手势 | Jetpack Compose | Android Developers
改进版
不用button触发,直接是点击加载,重写readfile,上面的readfile
函数是逐行加载的,这里的是异步一次性加载完毕;
package com.linkdom.readbook.fileio.readFile
import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.InputStreamReader
@Composable
fun Test5() {
val context = LocalContext.current
val text = remember { mutableStateOf("") }
val coroutineScope = rememberCoroutineScope()
// val scrollState = rememberScrollState()
remember {
coroutineScope.launch {
readFile(context, "第一章:刹车时代"){
text.value = it
}
}
}
Column (
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
){
Text(
text = text.value,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(10.dp)
)
}
}
@OptIn(DelicateCoroutinesApi::class)
fun readFile(
context: Context,
chapterName: String,
onRead: (String) -> Unit,
) {
GlobalScope.launch(Dispatchers.IO) {
val chapterPath = "$chapterName.txt"
val inputStream = context.assets.open(chapterPath)
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
var line: String? = bufferedReader.readLine()
var allText = ""
while (line != null) {
allText = allText + "\n" + line
line = bufferedReader.readLine()
}
onRead(allText)
}
}
@Preview(showBackground = true)
@Composable
fun Test51() {
Test5()
}