У вас есть XML ресурс массива строк, который содержит огромные строки. Как насчет того, чтобы хранить ваши огромные текстовые данные в отдельных файлах в каталоге assets, и, возможно, хранить имена файлов в ресурсе строкового массива. Затем по имени файла вы можете открыть и загрузить текстовые данные из файла активов.
Здесь я предлагаю способ эффективной загрузки огромных текстовых данных и отображения их в Activity.
Я использую поток для чтения огромных текстовых файлов в фоновом режиме.
Поток использует BufferedReader для чтения большого потока данных из файла. BufferedReader буферизует символы из потока данных, чтобы обеспечить эффективное чтение символов, массивов и строк.
В приведенном ниже примере поток использует BufferedReader для чтения текстовых данных построчно. Он читает текст за строкой и отправляет их в Activity через обработчик.
Это класс Kotlin, представляющий строку текста. Он содержит текстовую строку и номер строки.
TextLine.kt
class TextLine(
val lineNumber: Int,
val textLine: String
)
Это класс Thread, который читает текст построчно.
TextReaderThread.kt
class TextReaderThread(private val mInputStream: InputStream,
private val mTextLineHandler: Handler) : Thread() {
private val mStopped = AtomicBoolean(false)
override fun run() {
mStopped.set(false)
val bufferedReader = BufferedReader(InputStreamReader(mInputStream))
// Read first line
var lineNumber = 1
var textLine: String? = bufferedReader.readLine()
while (null != textLine) {
// Send read line to MainActivity
Message.obtain(mTextLineHandler, 0, TextLine(lineNumber, textLine)).sendToTarget()
// Check if thread is interrupted and stopped
if(mStopped.get()) break
// Read next line
textLine = bufferedReader.readLine()
lineNumber++
}
}
override fun interrupt() {
super.interrupt()
// Thread is interrupted to stop
mStopped.set(true)
}
}
Для отображения данных в режиме прокрутки я использую RecyclerView в Activity.
RecyclerView может эффективно обрабатывать и отображать большое количество данных при прокрутке данных пользователем.
Это макет одной строки данных, которая будет заполнена в RecyclerView. Слева TextView отображает номер строки, а справа TextView отображает строку текста.
list_item. xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/lineNumber"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="1"
android:textSize="11sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/textLine" />
<TextView
android:id="@+id/textLine"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="9"
android:textSize="12sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/lineNumber"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Это классы Adapter и ViewHolder для RecyclerView.
TextLineAdapter.kt
class TextLineAdapter(private val mContext: Context) : RecyclerView.Adapter<ViewHolder>() {
private val mItems = mutableListOf<TextLine>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false)
)
}
override fun getItemCount() = mItems.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.lineNumber.text = mItems[position].lineNumber.toString()
holder.textLine.text = mItems[position].textLine
}
fun addTextLine(textLine: TextLine) {
// Add new item to the end of list
mItems.add(textLine)
// Notify that an item is added to end of the list
notifyItemInserted(mItems.size - 1)
}
fun clear() {
// Clear item list
mItems.clear()
// Notify that full data set has been changed
notifyDataSetChanged()
}
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val lineNumber = view.lineNumber
val textLine = view.textLine
}
Это макет действия.
Activity_main. xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Это класс деятельности.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var mTextLineHandler: Handler
private lateinit var mTextReaderThread: Thread
private lateinit var mTextLineAdapter: TextLineAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Create Handler which uses main looper, to handle messages from TextReaderThread
mTextLineHandler = object : Handler(mainLooper) {
override fun handleMessage(msg: Message) {
// Add text line received from TextReaderThread to recycler view
mTextLineAdapter.addTextLine(msg.obj as TextLine)
}
}
// Set layout manager and adapter of recycler view
recyclerView.layoutManager = LinearLayoutManager(baseContext)
mTextLineAdapter = TextLineAdapter(baseContext)
recyclerView.adapter = mTextLineAdapter
}
override fun onResume() {
super.onResume()
// Clear recycler view
mTextLineAdapter.clear()
// Create TextReaderThread to read text lines from assets/alice29.txt file.
// Text lines read by TextReaderThread will be received and handled by mTextLineHandler.
mTextReaderThread = TextReaderThread(assets.open("alice29.txt"), mTextLineHandler)
// Start TextReaderThread
mTextReaderThread.start()
}
override fun onPause() {
super.onPause()
// Interrupt TextReaderThread to stop
mTextReaderThread.interrupt()
// Wait until TextReaderThread stops
mTextReaderThread.join()
}
}
В этом примере я использую только один большой текстовый файл с именем alice29.txt. Я загрузил файл alice29.txt из http://corpus.canterbury.ac.nz/descriptions/
В этом примере приложения считывается только один огромный текстовый файл (alice29.txt) и загружается содержимое в RecyclerView, как показано на следующих снимках экрана.
Верхняя часть RecyclerView.
Прокрутка до нижней части RecyclerView.
RecyclerView содержит 3609 строк текста.