web-dev-qa-db-fra.com

Causée par Java.lang.NullPointerException: tentative d'appeler la méthode virtuelle 'int Android.graphics.Bitmap.getWidth ()' sur une référence d'objet null

J'ai 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);
        }
    }
}

Dans cette classe il y a:

createScaledBitmap()

... qui renvoie une image bitmap redimensionnée.

Dans une autre classe, j'ai cette méthode:

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

Ce code fonctionnait bien dans de nombreux appareils. Mais il se brisait dans certains appareils. Est-ce que quelqu'un peut m'aider s'il vous plait ?

Je reçois un journal comme celui-ci: 

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)

S'il s'agit d'un problème d'autorisations, il ne devrait pas planter sous la version d'Android-M, mais il se bloque également sur certains appareils antérieurs à Android-M.

13
Pavan Bilagi

Le problème que vous rencontrez est que vous essayez de getWidth() sur votre unscaledBitmap dans la fonction createScaledBitmap. Clairement, votre unscaledBitmap est null parfois; et l'appel de getWidth() est à l'origine de l'exception Null Pointer.

La cause fondamentale est que decodeResource vous renvoie un null pour une raison quelconque.

Les raisons peuvent inclure -

  1. Pas de permission de lecture
  2. Le fichier image est corrompu
  3. Il n'y a pas assez de mémoire pour décoder le fichier
  4. La ressource n'existe pas
  5. Options non valides spécifiées dans la variable options.

Je suggérerais que vous modifiiez votre code pour inclure une vérification nulle sur le bitmap décodé, le consigner et le déboguer à partir de là sur les périphériques spécifiques sur lesquels l'erreur se produit.

Il se peut également que votre variable d’options que vous réutilisez soit interprétée différemment lors du deuxième appel à decodeResource. Vous pouvez essayer de passer un null là-bas.

Le code modifié devrait être comme suit -

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

Vous utilisez: Bitmap decodeFile (String pathName) Cette méthode peut renvoyer null si le décodage du fichier échoue. Je pense qu'il peut s'agir d'un problème d'autorisation sur un périphérique ou d'un format d'image non pris en charge GIF, essayez https://developer.Android.com/reference/Android/graphics/Movie.html

0
Anis BEN NSIR

Il y a quelques raisons peuvent causer l'erreur.

  1. Absence de permission dans AndroidManifest.xml. Lire ou écrire la permission.
  2. Le fichier n'existe pas ou vous essayez d'accéder à un fichier qui ne pourrait pas être décodé en tant que bitmap.

À partir du code que vous publiez, je ne trouve aucune erreur de logique. Voici mes suggestions:

  1. Changer une autre image et tester.

  2. Essayez d’utiliser la bibliothèque ImageLoader comme Glide ou Fresco et effectuez un test.

0
orzangleli