bitmap size exceeds VM budget
I've read many of the posts regarding this issue and I can't find one that would apply to my code (or at least that I can make the relation to).
I have a homescreen widget that displays in both landscape and portrait. If I continuously change the orientation of the device I get this in my logcat:
03-08 10:41:35.793: ERROR/dalvikvm-heap(1159): 4707316-byte external allocation too large for this process.
03-08开发者_如何学Go 10:41:35.793: ERROR/GraphicsJNI(1159): VM won't let us allocate 4707316 bytes 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): updateAppWidget couldn't find any view, using error view 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): android.view.InflateException: Binary XML file line #1: Error inflating class android.widget.LinearLayout 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.LayoutInflater.createView(LayoutInflater.java:513) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.LayoutInflater.inflate(LayoutInflater.java:385) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.widget.RemoteViews.apply(RemoteViews.java:930) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:219) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:155) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.appwidget.AppWidgetHost.createView(AppWidgetHost.java:218) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.launcher2.Launcher.bindAppWidget(Launcher.java:2393) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.launcher2.LauncherModel$Loader$LoaderThread$7.run(LauncherModel.java:1051) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.launcher2.DeferredHandler$Impl.handleMessage(DeferredHandler.java:48) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.os.Handler.dispatchMessage(Handler.java:99) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.os.Looper.loop(Looper.java:123) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.app.ActivityThread.main(ActivityThread.java:4645) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at java.lang.reflect.Method.invokeNative(Native Method) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at java.lang.reflect.Method.invoke(Method.java:521) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at dalvik.system.NativeStart.main(Native Method) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): Caused by: java.lang.reflect.InvocationTargetException 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.widget.LinearLayout.(LinearLayout.java:115) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at java.lang.reflect.Constructor.constructNative(Native Method) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at java.lang.reflect.Constructor.newInstance(Constructor.java:446) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.LayoutInflater.createView(LayoutInflater.java:500) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): ... 19 more 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.Bitmap.nativeCreate(Native Method) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.Bitmap.createBitmap(Bitmap.java:468) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.Bitmap.createBitmap(Bitmap.java:435) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.content.res.Resources.loadDrawable(Resources.java:1718) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.View.(View.java:1885) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.View.(View.java:1834) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): at android.view.ViewGroup.(ViewGroup.java:285) 03-08 10:41:35.793: WARN/AppWidgetHostView(1159): ... 23 more
My code is this which utilizes remoteViews:
public class WidgetLayoutBuilder {
public static final String DEG = "\u00B0";
public static final int LAYOUT_CURRENT = 1000;
public static final int LAYOUT_FORECAST = 1001;
/**
* Constructs current conditions layout.
*
* @param context
* @param wd
* @return
*/
public static RemoteViews buildCurrentLayout(Context context, int appWidgetId, ACCUWX_WeatherData wd){
Log.d("########", "remoteViews buildCurrentLayout");
// Return object
RemoteViews toRet = new RemoteViews(context.getPackageName(), R.layout.widget_current_layout);
String cityText = wd.getCityName();
String tempUnits = wd.getMetric() == 0 ? "F" : "C";
String iconId = "icon_" + wd.getCurrentIconCode();
// Populate views with weather data
toRet.setTextViewText (R.id.current_location_text, cityText);
toRet.setTextViewText (R.id.current_temp_text, wd.getCurrentTemperature() + DEG + tempUnits);
toRet.setTextViewText (R.id.current_conditions_text, wd.getCurrentConditions());
toRet.setImageViewResource (R.id.current_condition_image, ACCUWX.getDrawableId(iconId));
toRet.setTextViewText (R.id.current_hi_temp, context.getString(R.string.hi) + ": " + wd.getForecast().get(0).getDailyHigh() + DEG);
toRet.setTextViewText (R.id.current_lo_temp, context.getString(R.string.lo) +": " + wd.getForecast().get(0).getDailyLow() + DEG);
// Make alert icon visible if necessary.
int visibility = wd.getAlertIsActive() == 0 ? View.INVISIBLE : View.VISIBLE;
toRet.setViewVisibility(R.id.alert_icon, visibility);
if (MainActivity.mLocations == null)
MainActivity.mLocations = new ArrayList<String>();
if (MainActivity.mLocName == null)
MainActivity.mLocName = new String("");
if (!MainActivity.mLocations.contains(wd.getZipCode()) || !MainActivity.mLocName.contains(wd.getCityName()))
MainActivity.mLocations.add(wd.getZipCode());
MainActivity.isFromLocationSearchActivity = false;
// Launch SimpleWeather application intent
Intent intentAppLaunch = new Intent(context, MainActivity.class);
intentAppLaunch.putExtra(ACCUWX.Extras.LOCATION_CODE, wd.getZipCode());
intentAppLaunch.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingAppLaunch = PendingIntent.getActivity(context, appWidgetId, intentAppLaunch, PendingIntent.FLAG_CANCEL_CURRENT);
toRet.setOnClickPendingIntent(R.id.current_layout, pendingAppLaunch);
return toRet;
}
/**
* Returns pretty names for display purposes in the form 'city name, state name' for the US and 'cityname, countryname (region)' for other countries.
* @return
*/
public static String getPrettyName(ACCUWX_WeatherData wd){
String prettyName = "null";
String state = wd.getStateName();
String city = wd.getCityName();
String country = wd.getCountryName();
String countryCode = wd.getCountryCode();
if (countryCode.equalsIgnoreCase("us"))
prettyName = city + ", " + state;
else
prettyName = city + ", " + country + " (" + state + ")";
return prettyName;
}
/**
* Constructs deleted layout.
*
* @param context
* @return
*/
public static RemoteViews buildDeletedLayout(Context context){
Log.d("########", "remoteViews buildDeletedLayout");
return new RemoteViews(context.getPackageName(), R.layout.widget_deleted_layout);
}
}
Could the bitmap error be coming from the device itself and not an issue of my application?
Any help or direction is greatly appreciated!
bitmap size exceeds VM budget
This is just a generic error for memory leak. Monitor your memory usage using DDMS or various free apps in the real device and you will see your memory usage keeps going up until it bombs out (for me it was around 28MB).
You have a memory leak and only you can find it as you have all the source code. Look for bitmaps loaded and not released and cursors loaded and not closed.
This line:
ACCUWX.getDrawableId(iconId)
Make sure your drawable is not larger than it needs to be. When you load a Bitmap, you can load the boundaries first, then scale it, and load the scaled down version.
On Orientation change:
- Recycle the old Bitmap
- Only load the scaled version
i had a same problem, i found solution and write code for that.
hope that it will help u
OutofMemory error in Android
I am really affraid of this inter-android-blocks comunication:
if (MainActivity.mLocations == null)
MainActivity.mLocations = new ArrayList<String>();
if (MainActivity.mLocName == null)
MainActivity.mLocName = new String("");
if (!MainActivity.mLocations.contains(wd.getZipCode())
|| !MainActivity.mLocName.contains(wd.getCityName()))
MainActivity.mLocations.add(wd.getZipCode());
MainActivity.isFromLocationSearchActivity = false;
精彩评论