小部件更新的 RemoteViews 超出最大位图内存使用错误
Posted
技术标签:
【中文标题】小部件更新的 RemoteViews 超出最大位图内存使用错误【英文标题】:RemoteViews for widget update exceeds max bitmap memory usage error 【发布时间】:2012-11-09 19:13:08 【问题描述】:我有一个小部件,它解析 xml 提要并显示其标题和图像。在这个小部件中,我使用定期更改内容(即标题和图像)的服务。为此,我使用计时器类。当我们运行时这个小部件,一些内容显示没有任何问题,但一段时间后它强制关闭并显示错误,如“用于小部件更新的远程视图超出最大位图内存使用量(已使用:2465280 最大值:2304000)总内存不能超过填充所需的内存设备的屏幕一次”。请有人帮我解决这个问题...在此先感谢
这是我的 AppwidgetProvider=>
public class myappwidgetprovider extends AppWidgetProvider
public static String urls="http://www.abc.com/en/rssfeeds/9/latest/rss.xml";
// XML node keys
static final String KEY_HEAD = "item"; // parent node
//static final String KEY_TITLE = "title";
static final String KEY_DATE = "pubDate";
public static String headflag="english";
public static String[] Title;
public static String[] Description;
public static String[] Tit;
public static String[] Tit2;
public static String[] Desc;
public static String[] Desc2;
public static String[] image;
public static TextView flashnews;
public static int i=0;
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
Log.i("Tag", "onCreateView");
parse();
RemoteViews remoteViews;
ComponentName thisWidget = new ComponentName(context,myappwidgetprovider .class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
Intent intent = new Intent(context.getApplicationContext(),
Updatewidget.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
public static void parse()
URL url;
try
url = new URL(urls);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if((conn.getResponseCode() == HttpURLConnection.HTTP_OK))
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc;
doc = db.parse(url.openStream());
doc.getDocumentElement().normalize();
NodeList itemLst = doc.getElementsByTagName("item");
Description = new String[itemLst.getLength()];//........
Title = new String[itemLst.getLength()];
Tit=new String[itemLst.getLength()];
Tit2=new String[itemLst.getLength()];
Desc=new String[itemLst.getLength()];
Desc2=new String[itemLst.getLength()];
image= new String[itemLst.getLength()];
for(int i=0; i < itemLst.getLength(); i++)
Node item = itemLst.item(i);
if(item.getNodeType() == Node.ELEMENT_NODE)
Element ielem = (Element)item;
NodeList title = ielem.getElementsByTagName("title");
NodeList date = ielem.getElementsByTagName("pubDate");
NodeList description = ielem.getElementsByTagName("description");
Tit[i]= title.item(0).getChildNodes().item(0).getNodeValue();
Desc[i]= description.item(0).getChildNodes().item(0).getNodeValue();
Tit2[i]=Translate.title(Tit[i]);
Desc2[i]=Translate.description(Desc[i]);
if(headflag=="malayalam")
Desc2[i]=Desc2[i].replace("read more","IqSpXÂ");
Title[i] =Tit2[i];
if (Desc2[i].contains("<img "))
String img = Desc2[i].substring(Desc2[i].indexOf("<img "));
String cleanUp = img.substring(0, img.indexOf(">")+1);
img = img.substring(img.indexOf("src=") + 5);
int indexOf = img.indexOf("'");
if (indexOf==-1)
indexOf = img.indexOf("\"");
img = img.substring(0, indexOf);
//setImgLink(img);
if(headflag=="malayalam")
String img2=img.replace("files","files/imagecache/android_320");
Description[i]=Desc2[i].replace(img,img2);
image[i]=img2;
else
String img2=img.replace("files","files/imagecache/android_1_img");
Description[i]=Desc2[i].replace(img,img2);
image[i]=img2;
else
Description[i] =Desc2[i];
catch (MalformedURLException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (DOMException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (ParserConfigurationException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (SAXException e)
// TODO Auto-generated catch block
e.printStackTrace();
这是我的服务=>
public class Updatewidget extends Service
static String UPDATEMOOD ="UPDATEMOOD";
public Intent newintent;
public AppWidgetManager app;
public RemoteViews newviews;
public int[] newappid;
int i=0;
@Override
public void onStart(final Intent intent, int startId)
Log.i("Tag", "Service Called!!!!!!!!!!!!!");
newintent=intent;
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
newappid=allWidgetIds;
final AppWidgetManager appWidgetMan = AppWidgetManager.getInstance(this);
app=appWidgetMan;
final RemoteViews views = new RemoteViews(this.getPackageName(),R.layout.widget_main);
newviews=views;
views.setTextViewText(R.id.title, myappwidgetprovider.Title[0]);
Bitmap bitmap;
try
bitmap = BitmapFactory.decodeStream((InputStream)new URL(myappwidgetprovider.image[0]).getContent());
views.setImageViewBitmap(R.id.imageView4, bitmap);
catch (MalformedURLException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
appWidgetMan.updateAppWidget(allWidgetIds, views);
new ProgressAsyncTask().execute();
public class ProgressAsyncTask extends
AsyncTask<Void, Integer, Void>
@Override
protected Void doInBackground(Void... params)
// TODO Auto-generated method stub
int delay = 5000; // delay for 5 sec.
int period = 5000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
public void run()
i++;
if(i==5)
i=0;
int[] allWidgetIds = newintent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
newviews.setTextViewText(R.id.title, myappwidgetprovider .Title[i]);
Bitmap bitmap;
try
bitmap = BitmapFactory.decodeStream((InputStream)new URL(myappwidgetprovider .image[i]).getContent());
newviews.setImageViewBitmap(R.id.imageView4, bitmap);
catch (MalformedURLException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
app.updateAppWidget(allWidgetIds, newviews);
, delay, period);
return null;
@Override
public IBinder onBind(Intent intent)
// TODO Auto-generated method stub
return null;
【问题讨论】:
【参考方案1】:我刚刚解决了一个类似的问题。 但我没有从网络加载任何内容。 我的小部件针对不同的小部件尺寸显示不同的图像。对于某些屏幕,显示小部件 4x4 时会出现与您相同的错误。
这是我在 developer.google.com 上找到的:
RemoteViews 对象使用的总 Bitmap 内存不能超过 需要填充屏幕 1.5 倍,即。 (屏幕宽度 x 屏幕 高度 x 4 x 1.5) 字节。
所以我可以在小部件中限制我的位图大小以满足此要求。
在您的特定情况下,当从流中加载的位图超出可能时会发生错误。
我认为
的用法public static Bitmap decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options 选项)
使用适当的选项应该会有所帮助。 (可能您需要使用 inSampleSize 选项)。
希望我的帖子对您有所帮助。
【讨论】:
我想我已经解决了这个问题。无论如何,谢谢你:) @Rusanovskiy Artem:你怎么知道要传递给decodeStream()
的确切选项?如果您在小部件中有四个位图,并且您不知道源图像的大小,您怎么知道您必须使用哪个sampleSize
来防止Exception
?
@BasimSherif 你能解释一下你是如何解决这个问题的吗?谢谢!【参考方案2】:
Glide.with(mContext)
.load(imageUrl)
.override(480, 342)
....
override(...) 为我解决了问题。 没有更多错误,例如: 小部件更新的 RemoteViews 超出最大位图内存使用错误
【讨论】:
以上是关于小部件更新的 RemoteViews 超出最大位图内存使用错误的主要内容,如果未能解决你的问题,请参考以下文章
Android:将位图从本地存储加载到应用小部件(RemoteViews)
RemoteViews (Widget) 使用 Bitmap 时文本模糊
Android appwidget remoteviews没有更新