android – 使用getDrawingCache时是否存在最大位图大小?

我正在尝试在TextView中创建文本的位图.在过去,我使用getDrawingCache完成了这项工作.但是,现在我需要使用比以前更长的文本来创建TextView的位图.这导致getDrawingCache抛出NullPointerException.

虽然我说“文字长得多”,但我并不是说不合理的长篇.如果我创建一个600像素宽的24字体TextView,我会得到53行文本的异常(但不是52行).这有解决方法吗?

起初我认为this answer是一种解决方案,其中布局在画布上绘制.但是,这对我来说不起作用,因为我在编程之前以编程方式创建了TextView,并且在它们布局之前是the width and height are 0.我从来没有在屏幕上实际布局我的TextView.

代码供参考

private Bitmap getBitmap(Context context){

    final int NUMBER_OF_LINES = 53; // 53 crashes, 52 doesn't
    final int width = 600; // width of TextView in pixels
    final int fontSize = 24;

    // create string with NUMBER_OF_LINES
    StringBuilder testString = new StringBuilder();
    for (int i = 0; i < NUMBER_OF_LINES; i++) {
        testString.append("\n");
    }

    // Create TextView
    TextView tvText = new TextView(context);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    tvText.setTextSize(fontSize);
    tvText.setWidth(width);
    tvText.setLayoutParams(params);
    tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
    tvText.setText(testString);

    // Create bitmap
    tvText.setDrawingCacheEnabled(true);
    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
    tvText.buildDrawingCache(true);
    Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache()); // crashes here
    tvText.setDrawingCacheEnabled(false);

    // This also didn't work because width and height are 0
    /*Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);*/

    return bitmap;
}

空指针异常

06-21 14:20:24.628    8036-8036/com.example.testsomecode E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testsomecode/com.example.testsomecode.MainActivity}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
        ...
 Caused by: java.lang.NullPointerException
        at android.graphics.Bitmap.createBitmap(Bitmap.java:494)
        at com.example.testsomecode.MainActivity.getBitmap(MainActivity.java:57) // -> Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache());
        at com.example.testsomecode.MainActivity.onCreate(MainActivity.java:25)
        ...

注意

这不是IllegalArgumentException或OutOfMemoryError(至少不是外部的,尽管这可能是内部的原因.)

> Mysterious stacktrace in Android developer console (bitmap size exceeds 32bits)
> Strange out of memory issue while loading an image to a Bitmap object

解决方法:

您可以删除buildDrawingCache方法并使用canvas.由于您以编程方式构建视图,因此在获取位图之前还需要调用measure()和layout().

关键是:

    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
    Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);

这是完整的例子:

private Bitmap getBitmap(Context context){

    final int NUMBER_OF_LINES = 153;
    final int width = 600;
    final int fontSize = 24;

    // create string with NUMBER_OF_LINES
    StringBuilder testString = new StringBuilder();
    for (int i = 0; i < NUMBER_OF_LINES; i++) {
        testString.append("\n");
    }

    // Create TextView
    TextView tvText = new TextView(context);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    tvText.setTextSize(fontSize);
    tvText.setWidth(width);
    tvText.setLayoutParams(params);
    tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
    tvText.setText(testString);
    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());


    // Create the bitmap from the view
    Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    tvText.draw(canvas);

    return bitmap;
}
上一篇:android-java.lang.NullPointerException:在可扩展列表视图中显示数据库中的记录


下一篇:android-在“启动项目”期间发生内部错误.显示java.lang.NullPointerException