1

サービスから (放送受信機経由で) 毎分更新される時計ウィジェットを作成しましたが、数時間後には約 600MB の RAM が必要です。

ウィジェットは、いくつかの機能を備えたビットマップを毎分描画し、単純な で表示しImageViewます。

最初、ウィジェットは数 kb の RAM しか占有しませんが、数分後には数百 mb を消費します。新しいビットマップを作成する前に RAM をクリアする方法はありますか?

これはウィジェット コードの一部です。

public class Widget_01_Clock extends AppWidgetProvider {

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

Bitmap clock = WidgetPaint.getClockBitmap();


RemoteViews updateViews = new RemoteViews(context.getPackageName(),R.layout.w_01_clock);

updateViews.setImageViewBitmap(R.id.w_01_clock, clock);
}
}
4

2 に答える 2

1

その理由は、毎分新しいビットマップをメモリにロードするためです。したがって、ソリューションは次のいずれかになります。

  1. すでに提案されているように、次のビットマップのためにこのメモリブロックを将来使用するために、使用済みのビットマップをリサイクルします。

  2. スペースをあまりとらず、OutOfMemory例外を発生させない非常に小さな画像(サムネイル)で作業します。

個人的には両方を行う必要があると思います。画像ファイルのサムネイルバージョンを作成するコードは次のとおりです。

public static Bitmap decodeSampledBitmapFromFile(String path,
int reqWidth, int reqHeight) { // BEST QUALITY MATCH

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);

// Calculate inSampleSize
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;

if (height > reqHeight) {
    inSampleSize = Math.round((float)height / (float)reqHeight);
}

int expectedWidth = width / inSampleSize;

if (expectedWidth > reqWidth) {
    //if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger    SampSize..
    inSampleSize = Math.round((float)width / (float)reqWidth);
}


options.inSampleSize = inSampleSize;

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;

return BitmapFactory.decodeFile(path, options);
}
于 2013-03-07T15:35:31.497 に答える