由java.lang.NullPointerException引起:尝试调用虚拟方法';intandroid.graphics.Bitmap.getWidth()';关于空对象引用

由java.lang.NullPointerException引起:尝试调用虚拟方法';intandroid.graphics.Bitmap.getWidth()';关于空对象引用,android,android-activity,nullpointerexception,android-bitmap,Android,Android Activity,Nullpointerexception,Android Bitmap,我有BitmapScalingHelper.java: public class BitmapScalingHelper { public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight) { Options options = new Options(); options.inJustDecodeBounds = true;

我有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()
…返回缩放的位图图像

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

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;
    }
这段代码在许多设备中运行良好。但它在某些设备上崩溃了。谁能帮我一下吗

我得到的日志如下:

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之前的设备上也会崩溃。

您正在使用:
位图解码文件(字符串路径名)
如果文件解码失败,此方法可能返回null。 我认为这可能与某些设备上的权限问题或不支持的图像格式有关。
如果您使用的是GIF,请尝试

可能有一些原因会导致此错误

  • 缺少AndroidManifest.xml中的权限。读或写权限
  • 该文件不存在,或者您正试图访问无法解码为位图的文件
  • 从您发布的代码中,我找不到任何逻辑错误。以下是我的建议:

  • 更改另一个图像并进行测试

  • 尝试使用像Glide或Fresco这样的ImageLoader库并进行测试


  • 您面临的问题是,您正试图在
    createScaledBitmap
    函数中的
    unscaledBitmap
    上执行
    getWidth()
    。显然,您的
    unscaledBitmap
    有时是
    null
    ;调用
    getWidth()
    会导致空指针异常

    根本原因是无论出于何种原因,
    decodeResource
    都会返回空值

    原因可能包括-

  • 无阅读权限
  • 图像文件已损坏
  • 内存不足,无法解码该文件
  • 资源不存在
  • 选项变量中指定的选项无效
  • 我建议您修改代码,在解码的位图上包含一个空检查,记录它,然后在您看到错误发生的特定设备上进行调试

    也可能是您正在使用的选项变量在第二次调用
    decodeResource
    时被不同地解释。您可以尝试在那里传递null

    修改后的代码应如下所示-

    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;
        }
    }
    

    如果您使用创建不好的库jar,并且在gradle上将minifyEnabled设置为true,也可能导致此错误。

    简单回答: 按照以下步骤操作

  • 长按“单击已安装的应用程序”图标
  • 转到应用程序信息部分
  • 现在点击应用权限部分
  • 启用存储权限
  • 现在它工作正常了


    好吧,我反复遇到这个错误,我解决这个问题的方法是确保使用.png图像作为位图图像,并将其保存在drawable文件夹中。以前我把它作为向量资产使用。
    这对我来说很好。

    对于Android 10,将这一行添加到清单中:

    android:requestLegacyExternalStorage="true"
    
    请注意,您还必须添加所需的基本任务:

    读外部存储器,写外部存储器


    但是kitkat(4.4.4)中的程序也崩溃了。请提供清单权限以及如何将文件编码到主题目录名称?哪一行导致了异常(来自方法而不是整个类。)@PavanBilagi您找到了更好的内存管理解决方案吗,我发现在xperia xa中,这种情况几乎每次都会发生。但是如果您在调试模式下,在按f9之前在解码文件上稍等片刻,它就会工作。而且在几乎所有其他设备上都能正常工作。我也在用一些和你一样的东西。如果我把这一行放在其他android版本中会发生什么?