小部件更新的RemoteViews超过位图内存使用率最大值错误



我有一个小部件,它解析xml提要并显示其标题和图像。在这个小部件中,我使用了一个定期更改内容(即标题和图像)的服务。为此,我使用计时器类。当我们运行这个小部件时,一些内容会显示出来,没有任何问题,但过了一段时间后,它会强制关闭,并显示一个错误,如"小部件更新的RemoteViews超过了最大位图内存使用量(使用:2465280 max: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;
}


}

我刚刚解决了一个类似的问题。但我并没有从网上加载任何内容。我的小部件针对不同的小部件大小显示不同的图像。对于某些屏幕,显示小部件4x4时会出现与您相同的错误。

这就是我在developer.google.com上发现的:

RemoteViews对象使用的位图内存总量不能超过需要填充屏幕1.5倍,即(屏幕宽度x屏幕高度x4x1.5)字节。

所以我可以在小部件中对位图大小进行限制,以满足这一要求。

在您的特殊情况下,当从流加载的位图比可能的大时,就会发生错误。

我认为的前景

公共静态位图解码流(InputStream是Rect-outPadding,BitmapFactory。选项选择)

使用正确的选项应该会有所帮助。(可能需要使用inSampleSize选项)。

希望我的帖子能有所帮助。

演示RusArtM响应的第二部分

val bitmapOptions = BitmapFactory.Options()
bitmapOptions.inSampleSize = 4
val bitmap = BitmapFactory.decodeFile(codeData.imagePath, bitmapOptions)

应该可以解决这个问题。值大于1的inSampleSize,收缩图像。使用inSampleSize = 4,我们得到的图像是图像宽度/高度的1/4

这是的文档

谷歌发明了一个有趣的图片缓存。我不知道为什么,但它大大增加了系统的负载。这就是为什么我每次都这样做,并且不存储图片历史记录:

contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification_media);
Intent notify = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent butt = PendingIntent.getActivity(getApplicationContext(), 0, notify, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
contentView.setOnClickPendingIntent(R.id.ibShowApp, butt);
contentView.setTextViewText(R.id.tvTitle, title);
if (coverArt != null) {
if (coverCache != null) coverCache.recycle();
try {
coverCache = BitmapFactory.decodeFile(coverArt);
} catch (Throwable throwable) {
coverCache = null;
}
contentView.setImageViewBitmap(R.id.ivCover, coverCache);
} else if (coverCache != null) {
contentView.setImageViewBitmap(R.id.ivCover, null);
coverCache.recycle();
coverCache = null;
}
mBuilder.setContentTitle(title)
.setCustomBigContentView(contentView)
.setContent(contentView);
Notification not = mBuilder.build();
not.flags |= Notification.FLAG_NO_CLEAR;
startForeground(Constants.NOTIFICATION_ID, not);

最新更新