9

調用虛擬方法「詮釋android.graphics.Bitmap.getWidth()」我有BitmapScalingHelper.java:通過顯示java.lang.NullPointerException引起:嘗試上的空對象引用

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裝置也崩潰。

+0

哪一行導致異常 –

+0

@PavanBilagi沒有你發現內存管理更好的解決方案,我發現,在xperia xa幾乎每次都會發生這種情況。但是如果你在調試模式下並且在按f9之前在解碼文件上稍微等一下,它就可以工作。並且在幾乎所有其他設備中工作正常。我正在使用一些像你一樣的事情。 –

回答

4

你所面對的問題是,你是在createScaledBitmap函數試圖getWidth()unscaledBitmap。顯然,unscaledBitmap有時是null;並且調用getWidth()正在導致空指針異常。

根本原因是decodeResource無論出於何種原因都返回null。

的原因可能包括: -

  1. 沒有讀取權限
  2. 的圖像文件被損壞
  3. 沒有足夠的內存來解碼文件
  4. 的資源不存在
  5. 無效選項變量中指定的選項。

我建議你修改你的代碼,在解碼後的位圖上包含一個空值檢查,記錄下來並從那裏調試到你發現錯誤的特定設備上。

也可能是您正在重新使用的選項變量在第二次調用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; 
    } 
} 
0

正在使用:Bitmap decodeFile (String pathName) 如果文件解碼失敗,則此方法可能會返回null。 我認爲它可能與某些設備上的權限問題或不支持的圖像格式有關。 如果您使用的是GIF,請嘗試https://developer.android.com/reference/android/graphics/Movie.html

+0

但它在kitkat(4.4.4)中崩潰也 –

+0

您能否提供您的清單權限以及您的文件如何編碼爲THEME_DIRECTORY_NAME? –

0

有一些原因可能會導致錯誤。

  1. AndroidManifest.xml中缺少權限。讀取或寫入權限。
  2. 該文件不存在或者您試圖訪問不能解碼爲位圖的文件。

從您發佈的代碼,我找不到任何邏輯error.Here是我的建議:

  1. 更改另一個圖像和測試。

  2. 嘗試使用像Glide或Fresco一樣的ImageLoader庫並進行測試。

相關問題