如何避免包含无限ImageSpans的TextView的OutOfMemory?

时间:2011-04-28 07:01:04

标签: android bitmap textview out-of-memory

我正在开发一个手写笔记应用程序 该应用程序以这种方式工作:用户在触摸屏上编写(绘制)文本,应用程序将手写内容转换为位图(getBitmapFromHandwriting()),然后使用此位图生成SpannableString并在TextView中向用户显示(在我的例子中,我使用了EditText,但为了简单起见,让我们说它是TextView)。
以下是扩展TextView中的代码段:

    class MyTextView extends TextView{
            ...
            BitmapDrawable bmd = new BitmapDrawable(getBitmapFromHandwriting());
            int width = bmd.getIntrinsicWidth();
            int height = bmd.getIntrinsicHeight();
            bmd.setBounds(
                    (int)(height/4.0f),
                    (int)(height/4.0f),
                    (int)(width + height/4.0f),
                    (int)(height*5.0f/4.0f));
            final ImageSpan img = new ImageSpan(bmd);
            getText().setSpan(img, position, position+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            …
    }

在getBitmapFromHandwriting()中,应用程序为用户绘制的每个文本创建一个新的位图。

在笔记变大之前一切正常(意味着本机内存中有很多位图),当createBitmap()时抛出OutOfMemoryError。
经过大量的谷歌搜索,我学会了位图使用“本机记忆”,这是非常有限的 我也学会了gc for bitmap不会同时发生JVM的gc。因此,当位图肯定不再需要时,人们最好做bitmap.recycle() 根据以上知识,我认为我需要回收不可见文本的位图,并仅在必要时加载该位图(即可见)
在回收位图之前,我必须确保将来不会使用它,否则会得到“RuntimeException:Canvas:尝试使用循环位图......”
即,我必须清除附加到SpannableString的相应跨距。 (通过getText()。removeSpan()或getText()。clearSpans(),但这是另一个故事。)
为此,我需要告诉哪些字符串可见,哪些字符串不可见。在像GridView这样的ViewGroups中,我可以调用“getFirstVisiblePosition()”,但我不知道如何为TextView执行此操作。

我知道可以对位图进行下采样以支持更多位图,但我想要的是TextView支持UNLIMITED ImageSpans。
如果它是GridView或ListView,延迟加载实现将完成工作。但是如何在一个TextView中做到这一点? 将内容划分为多个页面理论上应该适用于某些情况,但在我的应用程序中,用户也可以“导出”该笔记。导出只是执行当前视图的副本(如何在不创建新位图的情况下进行导出是另一个问题,不会在此线程中讨论。)。如果笔记分为多个页面,则用户必须为每个页面“导出”,因此不能选择。

我的问题是:
    1.是否可以在TextView中确定可见字符串?
    2.有没有更好的方法(模式)来实现这样的“包含大量ImageSpans的TextView”而不会出现OutOfMemoryError?

任何想法都表示赞赏。提前谢谢!

0 个答案:

没有答案