Android 8.0以降で発生しています。
画像をディスプレイサイズに合わせて加工する処理があります。
そこで、ディスプレイサイズをfloatの変数に格納しているのですが、
その値が、突然変更(破壊)される現象が発生しております。

発生手順

  1. ディスプレイサイズをfloatの変数に格納する。
  2. Bitmap.create*の使用
  3. Bitmap.create*の使用前後で、ディスプレイサイズを格納したfloat変数の値が変わる。(壊れる?)

問題は上記の3番で、現象としては、Bitmap.create*の使用で、float変数のメモリ領域が
破壊されているように見えます。
floatの変数の型をdoubleやint等に変更すると本現象は発生しないことは確認しております。
変数の値は必ずしも壊れるわけではなく、壊れない場合もあります。

根本の原因が分からないため、暫定的な対応しかできない状態です。
本現象の原因をご存知の方がいれば、原因をご教示頂けないでしょうか?

開発環境

  • OS:Mac OS 10.11.6
  • Android Studio: 2.3.3, 3.0
  • compileSdkVersion: 23
  • buildToolVersion: 23.0.3
  • minSdkVersion:14
  • targetSdkVersion:23

発生端末

  • Nexus5X
    • Android 8.0, 8.1
    • Qualcomm Snapdragon 808 (MSM8992) 1.8GHz+1.4GHz ヘキサコア
    • メインメモリ 2GB

コードとログ

以下、該当のコードとなります。(抜粋)

// ディスプレイサイズをfloat変数に格納
float displayWidth = getResources().getDisplayMetrics().widthPixels;
float displayHeight = getResources().getDisplayMetrics().heightPixels;
float density = getResources().getDisplayMetrics().density;

try {
    writeLog(LOG_TAG, "image1_1 dw:[" + displayWidth + "] dh:[" + displayHeight + "]"); 
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image1); 
    writeLog(LOG_TAG, "image1_2 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "]"); 
    float widthScale = (float)displayWidth / (float) bmp.getWidth(); 
    writeLog(LOG_TAG, "image1_3 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "] scale:[" + widthScale + "]"); 
    bmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() * widthScale), (int)(bmp.getHeight() * widthScale), true); 
    writeLog(LOG_TAG, "image1_4 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "] scale:[" + widthScale + "]"); 
    ImageView imageView1 = (ImageView) findViewById(R.id.imageView1); 
    writeLog(LOG_TAG, "image1_5 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "] scale:[" + widthScale + "]"); 
    bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), (int) ((float)displayHeight * 0.18f - 6.0f * density)); 
    writeLog(LOG_TAG, "image1_6 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "] scale:[" + widthScale + "]");         
    imageView1.setImageBitmap(bmp); 
    writeLog(LOG_TAG, "image1_7 dw:[" + displayWidth + "] dh:[" + displayHeight + "] bw:[" + bmp.getWidth() +"] bh:[" + bmp.getHeight() + "] scale:[" + widthScale + "]"); 
} catch (Exception e) { 
    writeLog(LOG_TAG, "image1 exception", e, true); 
}

出力されたログは以下の通りです。(抜粋)

: image1_1 dw:[1080.0] dh:[1794.0] 
: image1_2 dw:[1080.0] dh:[1794.0] bw:[1916] bh:[646] 
: image1_3 dw:[1080.0] dh:[1794.0] bw:[1916] bh:[646] scale:[0.56367433] 
: image1_4 dw:[1080.0] dh:[1794.0] bw:[1080] bh:[364] scale:[0.56367433] 
: image1_5 dw:[1080.0] dh:[1794.0] bw:[1080] bh:[364] scale:[0.56367433] 
: image1_6 dw:[1.4644055E-27] dh:[1794.0] bw:[1080] bh:[307] scale:[0.56367433] 
: image1_7 dw:[1.4644055E-27] dh:[1794.0] bw:[1080] bh:[307] scale:[0.56367433] 

上記の通り、ログのimage1_5image1_6の間(Bitmap.createBitmap処理の後)で、
参照も代入もしていないdisplayWidthの値が1080から1.4644055E-27に変わります。
変わる値は固定ではなく、実行のたびに変わります。