我的应用从文本文件资源中读取大量数据,并在TextView中显示在屏幕上。 (最大的是~450k。)我逐行读取文件到SpannableStringBuffer(因为我删除了一些元数据,例如节名)。这种方法在两年内没有投诉,我在市场上有应用程序(超过7k有源设备安装),所以我知道代码是合理的正确。
但是,我收到了一位用户最近在LG Lucid(LGE VS840 4G,Android 2.3.6)上发布的报告,该文章被截断了。从日志条目中,我的应用程序在缓冲区中只有9,999个字符。这是SpannableStringBuffer的已知问题吗?是否有其他建议的方法来构建一个大的Spannable缓冲区?任何建议的解决方法?
除了保留每次附加到SpannableStringBuilder时更新的单独预期长度之外,我甚至没有很好的方法来检测错误,因为append接口返回对象,而不是错误!
我读取数据的代码是:
currentOffset = 0;
try {
InputStream is = getAssets().open(filename);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
ssb.clear();
jumpOffsets.clear();
ArrayList<String> sectionNamesList = new ArrayList<String>();
sectionOffsets.clear();
int offset = 0;
while (br.ready()) {
String s = br.readLine();
if (s.length() == 0) {
ssb.append("\n");
++offset;
} else if (s.charAt(0) == '\013') {
jumpOffsets.add(offset);
String name = s.substring(1);
if (name.length() > 0) {
sectionNamesList.add(name);
sectionOffsets.add(offset);
if (showSectionNames) {
ssb.append(name);
ssb.append("\n");
offset += name.length() + 1;
}
}
} else {
if (!showNikud) {
// Remove nikud based on Unicode character ranges
// Does not replace combined characters (\ufb20-\ufb4f)
// See
// http://en.wikipedia.org/wiki/Unicode_and_HTML_for_the_Hebrew_alphabet
s = s. replaceAll("[\u05b0-\u05c7]", "");
}
if (!showMeteg) {
// Remove meteg based on Unicode character ranges
// Does not replace combined characters (\ufb20-\ufb4f)
// See
// http://en.wikipedia.org/wiki/Unicode_and_HTML_for_the_Hebrew_alphabet
s = s.replaceAll("\u05bd", "");
}
ssb.append(s);
ssb.append("\n");
offset += s.length() + 1;
}
}
sectionNames = sectionNamesList.toArray(new String[0]);
currentFilename = filename;
Log.v(TAG, "ssb.length()=" + ssb.length() +
", daavenText.getText().length()=" +
daavenText.getText().length() +
", showNikud=" + showNikud +
", showMeteg=" + showMeteg +
", showSectionNames=" + showSectionNames +
", currentFilename=" + currentFilename
);
查看界面后,我打算用InputFilter替换showNikud和showMeteg案例。
答案 0 :(得分:0)
这是SpannableStringBuffer的已知问题吗?
我在源代码中看不到建议对SpannableStringBuffer
的大小进行严格限制。根据您的经验,我的猜测是,由于设备制造商的工程师做出了愚蠢的决定,这是该设备特有的问题。
任何建议的解决方法?
如果您通过Google Play商店分发,请在控制台中屏蔽此设备。
或者,不要使用一个大型TextView
,而是在TextView
中使用几个较小的ListView
小部件(这样它们可以被回收),每个段落可能有一个。这应该具有减少内存占用的额外好处。
或者,生成HTML并在WebView
。
答案 1 :(得分:0)
在编写(并让用户运行)测试应用后,他的设备似乎有SpannableStringBuilder
的这个任意限制,但不是StringBuilder
或StringBuffer
。我测试了一个快速更改以读入StringBuilder
,然后从结果中创建SpannableString
。不幸的是,这意味着在完全读入之前我无法创建跨度。
我必须考虑在TextView
中使用多个ListView
个对象,并使用Html.FromHtml
查看这是否适用于我的应用的长期计划。