StringBuilder и большой текст
Есть программа, которая считывает с БД текст из 5 млн. символов, и выводит их по частям на несколько страниц.
Есть метод, который обрабатывает этот текст, считывает сколько текста может вместиться в видимую часть экрана и возвращает лист страниц
pages.add(mSpannableStringBuilder.subSequence(startOffset, endOffset));
Проблема в том, что при считывании текста и присвоение его stringbuilder`у занимает много времени(7-10 сек).
Мог бы поделить текст на несколько частей запихнуть в List и передать list в publishProgress(). Но мне необходимо передать сначала ВЕСЬ ТЕКСТ в StringBuilder , потом чтобы из этого текста метод split() распределял текст на несколько страниц.
Подскажите пожалуйста, в моем случае как лучше обработать такой большой текст? Как в onProgressUpdate передавать текст по частям, если метод onProgressUpdate срабатывает только, после операции stringBuilder.append(modelList.get(i).getDetails());, которая занимает (7-10 сек)?
protected final List<CharSequence> doInBackground(List<CharSequence>... voids) {
SqliteDbHelper dbHelper;
ArrayList<BookModel> modelList;
dbHelper = new SqliteDbHelper(context);
modelList = new ArrayList<>();
dbHelper.openDataBase();
modelList = dbHelper.getDetails();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i <modelList.size() ; i++) {
stringBuilder.append(modelList.get(i).getDetails());
}
// final Spanned bodyText =
// getFormattedBookText(String.valueOf(modelList.get(0).getDetails()+modelList.get(1).getDetails()));
int desiredDimen;
if (context.getResources().getDisplayMetrics().heightPixels
> context.getResources().getDisplayMetrics().widthPixels) {
int dif = (context.getResources().getDisplayMetrics().heightPixels -
context.getResources().getDisplayMetrics().widthPixels) / 2;
desiredDimen = context.getResources().getDisplayMetrics().heightPixels - dif;
} else {
int dif = (context.getResources().getDisplayMetrics().widthPixels -
context.getResources().getDisplayMetrics().heightPixels) / 2;
desiredDimen = context.getResources().getDisplayMetrics().widthPixels - 300;
}
final PageSplitter pageSplitter =
new PageSplitter(desiredDimen,
desiredDimen * 2,
1f,
1f);
pageSplitter.append(stringBuilder);
TextPaint mPaintDetail = new TextPaint();
mPaintDetail.setColor(Color.DKGRAY);
mPaintDetail.setShadowLayer(2.0f, 0f, 2.0f, Color.DKGRAY);
mPaintDetail.setTextSize(10 * context.getResources().getDisplayMetrics().density);
mPaintDetail.setAntiAlias(true);
pageSplitter.split(mPaintDetail);
publishProgress(pageSplitter.getPages());
//Log.d("vadsf", "fav" + delegate.);
return delegate.splitBookDoInBackground();
}
public class PageSplitter {
private final int pageWidth;
private final int pageHeight;
private final float lineSpacingMultiplier;
private final float lineSpacingExtra;
private final List<CharSequence> pages = new ArrayList<>();
private final SpannableStringBuilder mSpannableStringBuilder = new SpannableStringBuilder();
public PageSplitter(int pageWidth,
int pageHeight,
float lineSpacingMultiplier,
float lineSpacingExtra) {
this.pageWidth = pageWidth;
this.pageHeight = pageHeight;
this.lineSpacingMultiplier = lineSpacingMultiplier;
this.lineSpacingExtra = lineSpacingExtra;
}
public void append(CharSequence charSequence) {
mSpannableStringBuilder.append(charSequence);
}
public void split(TextPaint textPaint) {
StaticLayout staticLayout = new StaticLayout(
mSpannableStringBuilder,
textPaint,
pageWidth,
Layout.Alignment.ALIGN_NORMAL,
lineSpacingMultiplier,
lineSpacingExtra,
false
);
int startLine = 0;
while (startLine < staticLayout.getLineCount()) {
int startLineTop = staticLayout.getLineTop(startLine);
int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight);
int endLineBottom = staticLayout.getLineBottom(endLine);
int lastFullyVisibleLine;
if (endLineBottom > startLineTop + pageHeight)
lastFullyVisibleLine = endLine - 1;
else
lastFullyVisibleLine = endLine;
int startOffset = staticLayout.getLineStart(startLine);
int endOffset = staticLayout.getLineEnd(lastFullyVisibleLine);
pages.add(mSpannableStringBuilder.subSequence(startOffset, endOffset));
Log.d("vasdf", String.valueOf(pages.get(0)));
startLine = lastFullyVisibleLine + 1;
}
}
public List<CharSequence> getPages() {
return pages;
}
}