

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

### コードとログ

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

[code]

    // ディスプレイサイズを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); 
    }
    
[/code]

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

[code]

    : 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] 
    
[/code]

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


CC BY-SA 3.0
2017-12-13T06:05:30.897
40241
2017-12-13T06:15:02.470
2020-06-17T08:14:45.997
-1
26627
question
android
Android 8.0でfloat変数のメモリ領域が破壊される。