为什么我的时钟小部件会在一段时间后使用大量内存?

时间:2013-03-07 15:22:57

标签: android bitmap widget ram

我创建了一个时钟小部件,每分钟从服务(通过广播接收器)更新,但在几个小时后它需要大约600mb的RAM。

小部件每分钟都会使用一些功能绘制位图,并通过简单的ImageView显示。

一开始,小部件只占用几公斤的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);
}
}

2 个答案:

答案 0 :(得分:1)

原因是每分钟都会将新位图加载到内存中。 所以你的解决方案应该是以下之一:

  1. 已经建议回收使用过的位图,以便将来使用此内存块用于下一个位图。

  2. 使用非常小的图像(缩略图),不会占用太多空间,并且不会导致OutOfMemory异常。

  3. 我个人认为你应该同时做这两件事,这里有一个代码来创建你的图像文件的缩略图版本:

    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);
    }
    

答案 1 :(得分:0)

我和你在同一条船上,我可能已经找到了一个解决方案来保持它有点低。经过大量的搜索和失败的结果,我可以得到我的时钟小部件(其背景图像高达800x800,溢出菜单图像,时间和日期 - 所有位图)通常不高于45mb;如果用户没有弄乱小部件的设置和自定义,它有时可以保持在20mb以下 - 因为我写这个,它被降到~11MB。 (然后在搞乱定制后,跳到41MB,现在大约一个小时的时间不到10MB)

你的问题是你的时钟有一些功能;我假设这是某种形象?好吧,我注意到我的每一分钟,每次更新,我都会重新绘制所有内容(背景,菜单,时间和日期)。我设法将其分为三个部分:菜单(必须为待定意图分开),背景+日期(仅当我有UPDATE意图或TIME CHANGED时才更新)和时间。我在Static类中使用SparseArray来保存背景+日期位图,然后当我只更新时间时,我调用该位图,所以我不必重新创建它。然后,当我设置远程视图时,我有类似的东西。

remoteViews.setImageViewBitmap(R.id.widget_consolidated, sparseArrayOfBitmaps.get(widgetNumber);
remoteViews.setImageViewBitmap(R.id.widget_time, functionToReturnTimeBitmap(arguments));
remoteViews.setImageViewBitmap(R.id.widget_overflow, functionToReturnMenuBitmap(arguments));

您可能需要做类似的事情。它不会总是保持低记忆(至少对我而言),但它似乎有帮助。