OutOfMemory bei Verwendung von AsyncTask und einem großen Bild

Die folgende Klasse analysiert einen RSS-Feed und zeichnet mit AsyncTask Bilder / Text auf den Bildschirm. Ich habe einen NASA-RSS-Feed verwendet. Letzte Nacht habe ich auf den gleichen Feed umgestellt, aber mit einem größeren Bild. Wenn ich jetzt versuche, die Aktualisierungsschaltfläche zu drücken, ist nicht mehr genügend Speicher vorhanden. Wie kann ich damit umgehen? Ich weiß, es liegt nur daran, dass das Bild so groß ist (ungefähr 6 MB im Vergleich zu 36 KB des anderen Bildes) und ich habe gelesen, dass es auch nicht hilft, wenn es statisch ist. Ich sehe keinen Weg daran vorbei, dass es statisch ist, da ich final_image als separate Instanz der Klasse abrufen muss, wenn Sie das Hintergrundbild als Bild festlegen. Also funktioniert alles unten mit einem kleineren Bild. Bei einem großen Bild funktioniert es einmal, aber wenn Sie versuchen, die Aktualisierungsschaltfläche (die nur RssParseSync.execute () ausführt) zu drücken, wird es nicht aktualisiert, und der folgende Fehler wird angezeigt. Ich möchte das größere Bild, da das kleine Bild beim Festlegen als Hintergrundbild sehr schlecht aussah.

public class RssParseSync extends AsyncTask<String,String,Bitmap>{  

        private Activity parent;
        private ProgressDialog dialog;
        private static Bitmap final_image; //must be static because a new instance is required to access getFinalImage();


        public RssParseSync(Activity parent){this.parent =parent;}//constructor to pass parent activity, need this to call findViewById

                private XmlPullParser makeParser(){

                }

                @Override
                protected Bitmap doInBackground(String... info){

                    URL iotd;
                    int count=info.length;
                    String title="",link="",description="",date="";

                    System.out.println("Number of params is "+count);

                    try{

                        iotd = new URL("http://www.nasa.gov/rss/lg_image_of_the_day.rss");//set URl
                        BufferedReader in;//new BufferedReader
                        in = new BufferedReader(new InputStreamReader(iotd.openStream()));//get rss

                        XmlPullParserFactory factory;
                        factory = XmlPullParserFactory.newInstance();//new factory


                        factory.setNamespaceAware(true);
                        XmlPullParser xpp;
                        xpp = factory.newPullParser();
                        xpp.setInput(in);

                        //rss is now parsed, free to use XmlPullParser functions to move around and evaulate the rss

                        int eventType;
                        eventType = xpp.getEventType();//returns an int which mean different things (START_DOCUMENT,START_TAG,etc)


                    while(eventType!=XmlPullParser.END_DOCUMENT){//while the document has words

                     switch(eventType){

                        case XmlPullParser.START_DOCUMENT://beginning of xml
                            break;
                        case XmlPullParser.START_TAG://case : at beginning of new tag
                            String tagName=xpp.getName();
                            System.out.println(tagName+" "+xpp.getDepth());

                            if(tagName.equals("title")&& xpp.getDepth()==4){//depth is specific to this certain rss feed, there are multiple tags with the same names
                                info[0]=xpp.nextText();
                                title=info[0];

                            }

                            if(tagName.equals("description")&& xpp.getDepth()==4){//depth is specific to this certain rss feed, there are multiple tags with the same names
                                info[1]=xpp.nextText();
                                description=info[1];    
                                StringBuilder tabbed=new StringBuilder(description);
                                tabbed.insert(0, "\t");
                                description=tabbed.toString();
                                //info[1]=description;
                            }

                            if(tagName.equals("pubDate")){//no depth needed, only one tag is named pubDate
                                info[2]=xpp.nextText();
                                date=info[2];                           
                            }

                            if(tagName.equals("enclosure")&&xpp.getDepth()==4){//this is where our image url is. this url is an attribute of the "enclosure" tag
                                //System.out.println("Enclosure has "+xpp.getAttributeCount());
                                for(int i=0; i<=xpp.getAttributeCount()-1; i++){
                                    System.out.println("in for");
                                    if(xpp.getAttributeName(i).equals("url")){
                                        link=xpp.getAttributeValue(i);
                                        info[3]=link;
                                        //System.out.println(link);
                                    }
                                }
                            }
                            break;

                        }
                        eventType=xpp.next();
                    }//switch

                        publishProgress(title,description,date,link);

                        in.close();//close BufferedReader
                    } catch (MalformedURLException e){
                        e.printStackTrace();
                    }catch(XmlPullParserException e1){
                        e1.printStackTrace();
                    }catch(IOException e2){
                        e2.printStackTrace();
                    }         
                    Bitmap image=getBitmapFromURL(info[3]);

                    return image;
                }
                @Override
                protected void onProgressUpdate(String... progress){
                    try {
                        System.out.println("onProgressUpdate");
                        resetDisplay(progress[0],progress[1],progress[2],progress[3]);//feeding parsed rss values, title, description, date, and link
                    } catch (MalformedURLException e) {//both exceptions are thrown by resetDisplay
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

                protected void onPostExecute(Bitmap image){//error when doing this in resetDisplay.... onPostExecute is invoked by the ui thread so this may be why it works here and not in resetDisplay
                    ImageView imageView=(ImageView) parent.findViewById(R.id.imageDisplay);
                    imageView.setImageBitmap(image);
                    final_image=image;
                    dialog.dismiss();

                }

                protected void onPreExecute(){
                     dialog=ProgressDialog.show(parent, "Loading", "Loading the image of the day");
                }

                private void resetDisplay(String title, String description,String date, String link) throws MalformedURLException, IOException{

                    TextView titleView=(TextView) parent.findViewById(R.id.imageTitle);
                    titleView.setText(title);

                    TextView dateView=(TextView) parent.findViewById(R.id.imageDate);
                    dateView.setText(date);

                    TextView descriptionView=(TextView) parent.findViewById(R.id.imageDescription);
                    descriptionView.setText(description);

                }

                public Bitmap getBitmapFromURL(String url) {
                    try {
                    Bitmap bitmap=null; 
                    InputStream input = new java.net.URL(url).openStream();
                    bitmap = BitmapFactory.decodeStream(input);//Decode an input stream into a bitmap. If the input stream is null, or cannot be used to decode a bitmap, the function returns null.
                    input.close();
                    return bitmap;
                    } catch (IOException ioe) { return null; }

                }

                public Bitmap getFinalImage(){
                    return final_image;
                };


    }//class

Aktualisierungsmethode

public void onRefresh(){
    System.out.println("in onRefresh");
    new RssParseSync(getActivity()).execute(title,description,date,link);
}

Logcat-Protokoll

07-20 17:44:18.470: I/System.out(7581): onProgressUpdate
07-20 17:44:18.770: D/dalvikvm(7581): GC_FOR_ALLOC freed 190K, 3% free 26538K/27299K, paused 46ms
07-20 17:44:18.770: I/dalvikvm-heap(7581): Forcing collection of SoftReferences for 24107536-byte allocation
07-20 17:44:18.790: D/dalvikvm(7581): GC_BEFORE_OOM freed 18K, 3% free 26519K/27299K, paused 23ms
07-20 17:44:18.790: E/dalvikvm-heap(7581): Out of memory on a 24107536-byte allocation.
07-20 17:44:18.790: I/dalvikvm(7581): "AsyncTask #2" prio=5 tid=13 RUNNABLE
07-20 17:44:18.790: I/dalvikvm(7581):   | group="main" sCount=0 dsCount=0 obj=0x40d6cac8 self=0x2412840
07-20 17:44:18.790: I/dalvikvm(7581):   | sysTid=7646 nice=10 sched=0/0 cgrp=default handle=32889544
07-20 17:44:18.790: I/dalvikvm(7581):   | schedstat=( 0 0 0 ) utm=7 stm=0 core=1
07-20 17:44:18.790: I/dalvikvm(7581):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-20 17:44:18.800: I/dalvikvm(7581):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:719)
07-20 17:44:18.800: I/dalvikvm(7581):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:791)
07-20 17:44:18.800: I/dalvikvm(7581):   at com.wajumbie.nasadailyimage.RssParseSync.getBitmapFromURL(RssParseSync.java:162)
07-20 17:44:18.800: I/dalvikvm(7581):   at com.wajumbie.nasadailyimage.RssParseSync.doInBackground(RssParseSync.java:116)
07-20 17:44:18.800: I/dalvikvm(7581):   at com.wajumbie.nasadailyimage.RssParseSync.doInBackground(RssParseSync.java:1)
07-20 17:44:18.800: I/dalvikvm(7581):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-20 17:44:18.800: I/dalvikvm(7581):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-20 17:44:18.800: I/dalvikvm(7581):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-20 17:44:18.800: I/dalvikvm(7581):   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
07-20 17:44:18.800: I/dalvikvm(7581):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-20 17:44:18.800: I/dalvikvm(7581):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-20 17:44:18.800: I/dalvikvm(7581):   at java.lang.Thread.run(Thread.java:864)
07-20 17:44:18.800: E/dalvikvm(7581): Out of memory: Heap Size=34019KB, Allocated=26519KB, Limit=49152KB
07-20 17:44:18.800: E/dalvikvm(7581): Extra info: Footprint=27299KB, Allowed Footprint=34019KB, Trimmed=1212KB
07-20 17:44:18.800: D/skia(7581): --- decoder->decode returned false
07-20 17:44:18.800: W/dalvikvm(7581): threadid=13: thread exiting with uncaught exception (group=0x40aa3a08)
07-20 17:44:18.810: E/AndroidRuntime(7581): FATAL EXCEPTION: AsyncTask #2
07-20 17:44:18.810: E/AndroidRuntime(7581): java.lang.RuntimeException: An error occured while executing doInBackground()
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.lang.Thread.run(Thread.java:864)
07-20 17:44:18.810: E/AndroidRuntime(7581): Caused by: java.lang.OutOfMemoryError: (Heap Size=34019KB, Allocated=26519KB)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:719)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:791)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at com.wajumbie.nasadailyimage.RssParseSync.getBitmapFromURL(RssParseSync.java:162)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at com.wajumbie.nasadailyimage.RssParseSync.doInBackground(RssParseSync.java:116)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at com.wajumbie.nasadailyimage.RssParseSync.doInBackground(RssParseSync.java:1)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-20 17:44:18.810: E/AndroidRuntime(7581):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-20 17:44:18.810: E/AndroidRuntime(7581):     ... 5 more
07-20 17:44:19.061: D/OpenGLRenderer(7581): Flushing caches (mode 0)
07-20 17:44:19.061: D/memalloc(7581): ion: Unmapping buffer  base:0x52738000 size:2088960
07-20 17:44:19.061: D/memalloc(7581): ion: Unmapping buffer  base:0x52f7c000 size:2088960
07-20 17:44:19.061: D/memalloc(7581): ion: Unmapping buffer  base:0x53477000 size:2088960
07-20 17:44:19.081: D/OpenGLRenderer(7581): Flushing caches (mode 0)
07-20 17:44:19.111: D/memalloc(7581): ion: Unmapping buffer  base:0x52bea000 size:524288
07-20 17:44:19.121: D/memalloc(7581): ion: Unmapping buffer  base:0x5367d000 size:524288
07-20 17:44:19.121: D/memalloc(7581): ion: Unmapping buffer  base:0x53326000 size:524288
07-20 17:44:19.141: D/OpenGLRenderer(7581): Flushing caches (mode 2)
07-20 17:44:19.181: E/WindowManager(7581): Activity com.wajumbie.nasadailyimage.NasaAppActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40d92b30 that was originally added here
07-20 17:44:19.181: E/WindowManager(7581): android.view.WindowLeaked: Activity com.wajumbie.nasadailyimage.NasaAppActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40d92b30 that was originally added here
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:380)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:372)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.Window$LocalWindowManager.addView(Window.java:557)
07-20 17:44:19.181: E/WindowManager(7581):  at android.app.Dialog.show(Dialog.java:301)
07-20 17:44:19.181: E/WindowManager(7581):  at android.app.ProgressDialog.show(ProgressDialog.java:116)
07-20 17:44:19.181: E/WindowManager(7581):  at android.app.ProgressDialog.show(ProgressDialog.java:99)
07-20 17:44:19.181: E/WindowManager(7581):  at android.app.ProgressDialog.show(ProgressDialog.java:94)
07-20 17:44:19.181: E/WindowManager(7581):  at com.wajumbie.nasadailyimage.RssParseSync.onPreExecute(RssParseSync.java:142)
07-20 17:44:19.181: E/WindowManager(7581):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561)
07-20 17:44:19.181: E/WindowManager(7581):  at android.os.AsyncTask.execute(AsyncTask.java:511)
07-20 17:44:19.181: E/WindowManager(7581):  at com.wajumbie.nasadailyimage.NasaDailyImage.onRefresh(NasaDailyImage.java:57)
07-20 17:44:19.181: E/WindowManager(7581):  at com.wajumbie.nasadailyimage.NasaAppActivity$1.run(NasaAppActivity.java:48)
07-20 17:44:19.181: E/WindowManager(7581):  at com.wajumbie.nasadailyimage.NasaAppActivity.onRefreshClicked(NasaAppActivity.java:51)
07-20 17:44:19.181: E/WindowManager(7581):  at java.lang.reflect.Method.invokeNative(Native Method)
07-20 17:44:19.181: E/WindowManager(7581):  at java.lang.reflect.Method.invoke(Method.java:511)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.View$1.onClick(View.java:3066)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.View.performClick(View.java:3538)
07-20 17:44:19.181: E/WindowManager(7581):  at android.view.View$PerformClick.run(View.java:14330)
07-20 17:44:19.181: E/WindowManager(7581):  at android.os.Handler.handleCallback(Handler.java:607)
07-20 17:44:19.181: E/WindowManager(7581):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-20 17:44:19.181: E/WindowManager(7581):  at android.os.Looper.loop(Looper.java:156)
07-20 17:44:19.181: E/WindowManager(7581):  at android.app.ActivityThread.main(ActivityThread.java:5008)
07-20 17:44:19.181: E/WindowManager(7581):  at java.lang.reflect.Method.invokeNative(Native Method)
07-20 17:44:19.181: E/WindowManager(7581):  at java.lang.reflect.Method.invoke(Method.java:511)
07-20 17:44:19.181: E/WindowManager(7581):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-20 17:44:19.181: E/WindowManager(7581):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-20 17:44:19.181: E/WindowManager(7581):  at dalvik.system.NativeStart.main(Native Method)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage