由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

查看:110
本文介绍了由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.

推荐答案

您面临的问题是,您试图在 unscaledBitmap 中的 getWidth() createScaledBitmap 函数.显然,您的 unscaledBitmap 有时为 null ;并调用 getWidth()会导致Null Pointer异常.

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. 在options变量中指定的无效选项.

我建议您修改代码,以对解码后的位图进行空检查,将其记录下来,然后在看到错误发生的特定设备上进行调试.

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 的过程中,可能还会重复使用所使用的options变量.您可以尝试在其中传递null.

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.

修改后的代码应如下-

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天全站免登陆