RemoteViews的窗口更新超过最高位内存使用错误 [英] RemoteViews for widget update exceeds max bitmap memory usage error

查看:1079
本文介绍了RemoteViews的窗口更新超过最高位内存使用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小工具,解析XML数据源,并显示其标题和image.In这个小工具我使用的是定期更改的内容(即标题和图像)。为此我使用的定时器class.When我们运行服务这个小工具,一些内容显示,没有任何问题,但一段时间后,它强制关闭,并显示类似RemoteViews的窗口更新的误差超过最高位内存使用(使用:2465280最大值:2304000)的总内存不能超过要求填写该设备的屏幕一次。请有人帮我解决这个问题?在此先感谢

下面是我的AppwidgetProvider =>

 公共类myappwidgetprovider扩展AppWidgetProvider {
    公共静态字符串的URL =htt​​p://www.abc.com/en/rssfeeds/9/latest/rss.xml;
    // XML节点键
    静态最后弦乐KEY_HEAD =项目; //父节点
    //静态最后弦乐KEY_TITLE =称号;
    静态最后弦乐KEY_DATE =pubdate的;
    公共静态字符串headflag =英语;
    公共静态的String []标题;
        公共静态的String []说明;
        公共静态的String []山雀;
        公共静态的String [] TIT2;
        公共静态的String []说明;
        公共静态的String [] DESC2;
        公共静态的String []的图像;
    公共静态的TextView flashnews;

    公共静态INT I = 0;

     公共无效的OnUpdate(上下文的背景下,AppWidgetManager appWidgetManager,INT [] appWidgetIds)
        {

         Log.i(标签,onCreateView);
         解析();


           RemoteViews remoteViews;
                        组件名thisWidget =新的组件名(背景下,myappwidgetprovider的.class);

                INT [] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

                意向意图=新的意图(context.getApplicationContext()
                        Updatewidget.class);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,allWidgetIds);
                            context.startService(意向);

               }





     公共静态无效解析()
     {

            URL网址;

            尝试 {

                URL =新的URL(网址);
                HttpURLConnection的康恩=(HttpURLConnection类)url.openConnection();
                如果((conn.getResponse code()== HttpURLConnection.HTTP_OK)){
                      DocumentBuilderFactory的DBF = DocumentBuilderFactory.newInstance();
                      DocumentBuilder的DB = dbf.newDocumentBuilder();
                      文档文档;
                      文档= db.parse(url.openStream());
                      doc.getDocumentElement()归()。

                      节点列表itemLst = doc.getElementsByTagName(项目);
                      说明=新的String [itemLst.getLength(); // ........
                      标题=新的String [itemLst.getLength()];
                      山雀=新的String [itemLst.getLength()];
                      TIT2 =新的String [itemLst.getLength()];
                      说明=新的String [itemLst.getLength()];
                      DESC2 =新的String [itemLst.getLength()];
                      图像=新的String [itemLst.getLength()];

                      的for(int i = 0; I< itemLst.getLength();我++){

                            节点项= itemLst.item(我);
                            如果(item.getNodeType()== Node.ELEMENT_NODE){
                                  元素ielem =(元)项目;
                                  节点列表标题= ielem.getElementsByTagName(标题);
                                  节点列表日期= ielem.getElementsByTagName(pubdate的);
                                  节点列表说明= ielem.getElementsByTagName(说明);
                                  。山雀[I] = title.item(0).getChildNodes()项目(0).getNodeValue();
                                  。说明[I] = description.item(0).getChildNodes()项目(0).getNodeValue();
                                  TIT2 [I] = Translate.title(山雀[I]);
                                  DESC2 [I] = Translate.description(商品说明[I]);
                                  如果(headflag ==马来亚)
                                    {
                                      DESC2 [i] = DESC2 [I] .replace(更多,IqSpXÂ);
                                    }
                                  标题[i] = TIT2 [I]
                                  如果(DESC2 [I]。载(&所述; IMG)){
                                      字符串IMG = DESC2 [I] .substring(DESC2 [I] .indexOf(< IMG));
                                      串清理= img.substring(0,img.indexOf(>中)+ 1);
                                      的img = img.substring(img.indexOf(SRC =)+。5);
                                      INT的indexOf = img.indexOf(');
                                      如果(的indexOf ==  -  1){
                                          的indexOf = img.indexOf(\);
                                        }
                                      的img = img.substring(0,的indexOf);

                                // setImgLink(IMG);
                                    如果(headflag ==马来亚)
                                    {
                                        字符串IMG2 = img.replace(文件,文件/ imagecache / android_320);
                                        说明[I] = DESC2 [I] .replace(IMG,IMG2);
                                        图像[我] = IMG2;
                                    }

                                其他
                                {
                                    字符串IMG2 = img.replace(文件,文件/ imagecache / android_1_img);
                                    说明[I] = DESC2 [I] .replace(IMG,IMG2);
                                    图像[我] = IMG2;
                                }
                                  }
                                其他
                                {
                                    说明[I] = DESC2 [I]
                                }



                            }

                          }

                        }
            }赶上(MalformedURLException异常E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }赶上(抛出:DOMException E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }赶上(IOException异常E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }赶上(的ParserConfigurationException E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }赶上(的SAXException E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }
     }

}
 

和这里是我的服务=>

 公共类Updatewidget延伸服务{
    静态字符串UPDATEMOOD =UPDATEMOOD;
    公众意向newintent;
    公共AppWidgetManager应用;
    公共RemoteViews newviews;
    公众诠释[] newappid;
    INT I = 0;
    @覆盖
    公共无效ONSTART(最终意图的意图,诠释startId){

         Log.i(标签,服务叫!!!!!!!!!!!!!);

         newintent =意图;
                 INT [] allWidgetIds =意图
                    .getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
         newappid = allWidgetIds;

         最后AppWidgetManager appWidgetMan = AppWidgetManager.getInstance(本);
         应用= appWidgetMan;
         最后RemoteViews意见=新RemoteViews(this.getPackageName(),R.layout.widget_main);
         newviews =意见;
         views.setTextViewText(R.id.title,myappwidgetprovider.Title [0]);
         点阵位图;
            尝试 {
                位= BitmapFactory.de codeStream(。(InputStream的)新的URL(myappwidgetprovider.image [0])的getContent());


                views.setImageViewBitmap(R.id.imageView4,位图);
            }赶上(MalformedURLException异常E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }赶上(IOException异常E){
                // TODO自动生成的catch块
                e.printStackTrace();
            }
         appWidgetMan.updateAppWidget(allWidgetIds,意见);

         新ProgressAsyncTask()执行()。








    }



     公共类ProgressAsyncTask扩展
        AsyncTask的<太虚,整型,太虚> {

        @覆盖
        保护无效doInBackground(虚空...... PARAMS){
            // TODO自动生成方法存根
             INT延迟= 5000; //延迟5秒。

             INT周期= 5000; //重复每个秒。

             定时器定时=新的Timer();
              timer.scheduleAtFixedRate(新的TimerTask(){

                     公共无效的run(){
                         我++;
                         如果(我== 5)
                         {
                             I = 0;
                         }

                         INT [] allWidgetIds = newintent
                                    .getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
                                 newviews.setTextViewText(R.id.title,myappwidgetprovider .title伪[I]);
                         点阵位图;
                            尝试 {
                                位= BitmapFactory.de codeStream((InputStream的)新的URL(myappwidgetprovider在图像配[I])的getContent());


                                newviews.setImageViewBitmap(R.id.imageView4,位图);
                            }赶上(MalformedURLException异常E){
                                // TODO自动生成的catch块
                                e.printStackTrace();
                            }赶上(IOException异常E){
                                // TODO自动生成的catch块
                                e.printStackTrace();
                            }
                         app.updateAppWidget(allWidgetIds,newviews);
                                 }


                     },延迟,周期);
            返回null;
        }
     }

    @覆盖
    公众的IBinder onBind(意向意图){
        // TODO自动生成方法存根
        返回null;
    }





}
 

解决方案

我刚刚解决了类似的问题。 但我不加载从网络的任何内容。 我的小部件是显示不同的图像,不同的部件尺寸。而对于一些屏幕出现了同样的错误,因为你的显示部件4x4的。

这是我在developer.google.com发现:

  

使用的RemoteViews对象中总的位图的内存不能超过   这需要填写的屏的1.5倍,即。 (屏幕宽度X屏幕   身高×4×1.5)字节。

所以我可以只是把一个限制我的位图大小的小工具,以适应这一要求。

在特定的情况下,错误occures时,从流中的位图装载比可能较大。

我想的ussage

  

公共静态位图德codeStream(InputStream的是,矩形outPadding,   BitmapFactory.Options选择采用)

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

希望我的职位是有帮助的。

I have a widget that parses xml feed and display its title and image.In this widget I am using a service that periodically changes the contents(ie, title and image).For this I am using timer class.When we run this widget, some contents are displayed without any problem but after sometime it force closes and shows an error like "RemoteViews for widget update exceeds maximum bitmap memory usage(used:2465280 max:2304000) The total memory can't exceed that required to fill the device's screen once". Please some one help me to solve this issue...Thanks in advance

Here is my 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();
            }
     }

}

And Here is my service=>

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





}

解决方案

I just solved a similar problem. But I wasn't loading any content from web. My widget was displaying different images for different widget sizes. And for some screens there was the same error as yours displaying widget 4x4.

That what I've found at developer.google.com:

The total Bitmap memory used by the RemoteViews object cannot exceed that required to fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.

So I was able just to put a restriction on my bitmap size in widget to fit this requirement.

In your particular case the error occures when a bitmap loading from stream is larger than possible.

I think the ussage of

public static Bitmap decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options opts)

with proper options should help. (possible you need to use inSampleSize option).

Hope my post was helpful.

这篇关于RemoteViews的窗口更新超过最高位内存使用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆