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.
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 -
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;
}
}
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
Il y a quelques raisons peuvent causer l'erreur.
À partir du code que vous publiez, je ne trouve aucune erreur de logique. Voici mes suggestions:
Changer une autre image et tester.
Essayez d’utiliser la bibliothèque ImageLoader comme Glide ou Fresco et effectuez un test.