由 java.lang.NullPointerException 引起:尝试在空对象引用上调用虚拟方法“int android.graphics.Bitmap.getWidth()" [英] Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference

查看:24
本文介绍了由 java.lang.NullPointerException 引起:尝试在空对象引用上调用虚拟方法“int android.graphics.Bitmap.getWidth()"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 BitmapScalingHelper.java:

I have BitmapScalingHelper.java:

public class BitmapScalingHelper
{
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;

        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        return unscaledBitmap;
    }

    public static Bitmap decodeFile(String filePath, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        Bitmap unscaledBitmap = BitmapFactory.decodeFile(filePath, options);

        return unscaledBitmap;
    }


    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
    {
        final float srcAspect = (float)srcWidth / (float)srcHeight;
        final float dstAspect = (float)dstWidth / (float)dstHeight;

        if (srcAspect > dstAspect)
        {
            return srcWidth / dstWidth;
        }
        else
        {
            return srcHeight / dstHeight;
        }
    }

    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight)
    {
        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight());

        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight);

        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
                Config.ARGB_8888);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

    public static Rect calculateSrcRect(int srcWidth, int srcHeight)
    {
        System.out.print("Scr" + srcWidth + " " + srcHeight);
        return new Rect(0, 0, srcWidth, srcHeight);
    }

    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
    {
        final float srcAspect = (float)srcWidth / (float)srcHeight;
        final float dstAspect = (float)dstWidth / (float)dstHeight;

        if (srcAspect > dstAspect)
        {
            return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
        }
        else
        {
            return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
        }
    }
}

在这个类中有:

createScaledBitmap()

...返回缩放的位图图像.

...which returns a scaled bitmap image.

在另一个类中,我有这个方法:

In another class, I have this method:

public Bitmap readSelectedBitmapFromFile(Context context, String fileName)
    {
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(metrics);

        Bitmap scaledBitmap = getDefaultBitmap(context);

        try {
            File themeParentDir = context.getDir(THEME_DIRECTORY_NAME, Context.MODE_PRIVATE); //Creating an internal dir;
            File themeSubDir = new File(themeParentDir, THEME_SUB_DIRECTORY_NAME + getThemeBasedDirectoryNumber(m_SelectedTheme));
            themeSubDir.mkdir();

            File themeFileWithinDir = new File(themeSubDir, fileName); //Getting a file within the dir.

            if(themeFileWithinDir.exists())
            {
                // Part 1: Decode image
                Bitmap unscaledBitmap = BitmapScalingHelper.decodeFile(themeFileWithinDir.getPath(), metrics.widthPixels, metrics.heightPixels);

                // Part 2: Scale image
                scaledBitmap = BitmapScalingHelper.createScaledBitmap(unscaledBitmap, metrics.widthPixels, metrics.heightPixels);
                unscaledBitmap.recycle();
            }

            m_SelectedBitmap = scaledBitmap;

        }
        catch (Error e) {
            e.printStackTrace();
        }

        return scaledBitmap;
    }

此代码在许多设备上运行良好.但它在某些设备上崩溃了.有人可以帮我吗?

This code was working fine in many devices. But it was crashing in some devices. Can any one please help me out ?

我收到这样的日志:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
       at android.app.ActivityThread.access$1100(ActivityThread.java:222)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:158)
       at android.app.ActivityThread.main(ActivityThread.java:7229)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
       at in.plackal.lovecyclesfree.util.BitmapScalingHelper.createScaledBitmap(SourceFile:62)
       at in.plackal.lovecyclesfree.general.ThemeManager.readSelectedBitmapFromFile(SourceFile:202)
       at in.plackal.lovecyclesfree.activity.SplashActivity.onCreate(SourceFile:70)
       at android.app.Activity.performCreate(Activity.java:6876)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
       at android.app.ActivityThread.access$1100(ActivityThread.java:222)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:158)
       at android.app.ActivityThread.main(ActivityThread.java:7229)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

如果是权限问题,它应该不会在 Android-M 版本以下崩溃,但在一些 Android-M 之前的设备中也会崩溃.

If it's a permissions issue, it should not crash below the Android-M version, but it is crashing in some pre-Android-M devices also.

推荐答案

您面临的问题是您正试图在您的 unscaledBitmapgetWidth()createScaledBitmap 函数.显然,您的 unscaledBitmap 有时是 null;并调用 getWidth() 导致空指针异常.

The problem you are facing is that you are trying to getWidth() on your unscaledBitmap in the createScaledBitmap function. Clearly, your unscaledBitmap is null sometimes; and calling getWidth() is causing the Null Pointer exception.

根本原因是 decodeResource 无论出于何种原因都返回 null.

The root cause is that decodeResource is returning you a null for whatever reason.

原因可能包括 -

  1. 没有读取权限
  2. 图像文件已损坏
  3. 没有足够的内存来解码文件
  4. 资源不存在
  5. 在选项变量中指定的选项无效.

我建议你修改你的代码,在解码的位图上包含一个空检查,记录它并从那里在你看到错误发生的特定设备上进行调试.

I'd suggest that you modify your code to include a null-check on the decoded bitmap, log it and debug from there on the specific devices that you see the error occurring.

也可能是您正在重用的选项变量在第二次调用 decodeResource 时被不同地解释.您可以尝试在那里传递一个空值.

It may also be that your options variable that you are re-using is being interpreted differently in the second call to decodeResource. You might try passing a null there.

修改后的代码应该如下-

The modified code should be as follows -

public class BitmapScalingHelper
{
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;

        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        options = new Options(); 
        //May use null here as well. The funciton may interpret the pre-used options variable in ways hard to tell.
        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        if(unscaledBitmap == null)
        {
            Log.e("ERR","Failed to decode resource - " + resId + " " + res.toString());
            return null;
        }

        return unscaledBitmap;
    }
}

这篇关于由 java.lang.NullPointerException 引起:尝试在空对象引用上调用虚拟方法“int android.graphics.Bitmap.getWidth()"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆