Hier ist der Code, in dem ich versuche, ein großes Bild herunterzuladen.

RequestOptions requestOptions = new RequestOptions();
            requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
            requestOptions.skipMemoryCache(true);
Glide.with(this)
 .load(rogImage)
 .apply(requestOptions)
 .listener(new RequestListener<Drawable>() {
        @Override
        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
            ProgressBarHandler.unloadProgressScreen(getActivity());
            return false;
        }
    })
    .into(new SimpleTarget<Drawable>() {
        @Override
        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
            tempImageView.setImageDrawable(resource)
        }

    });

Ich lande die meiste Zeit in der fehlgeschlagenen Methode onLoad mit OutOfMemoryError.

Wenn ich im Gerätedateie-Explorer eingecheckt habe, werden die Bilder heruntergeladen, aber nicht zum zweiten Mal in die Bildansicht geladen. Zum ersten Mal funktioniert es perfekt für große Bilder.

Ich wiederhole den gleichen Code für den zweiten Anruf.

Unten ist die tatsächliche Fehlermeldung in Android Studio.

Glide: Root cause (1 of 13)
    java.lang.OutOfMemoryError: Failed to allocate a 210639956 byte allocation with 16777216 free bytes and 197MB until OOM
  at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
  at android.graphics.Bitmap.nativeCreate(Native Method)
  at android.graphics.Bitmap.createBitmap(Bitmap.java:975)
  at android.graphics.Bitmap.createBitmap(Bitmap.java:946)
  at android.graphics.Bitmap.createBitmap(Bitmap.java:913)
  at com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool.createBitmap(LruBitmapPool.java:149)
  at com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool.getDirty(LruBitmapPool.java:142)
  at com.bumptech.glide.load.resource.bitmap.Downsampler.setInBitmap(Downsampler.java:688)
  at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeFromWrappedStreams(Downsampler.java:297)
  at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:207)
  at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:160)
  at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:33)
  at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:16)
  at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:72)
  at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:55)
  at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:45)
  at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:58)
  at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:43)
  at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:498)
  at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:469)
  at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:455)
  at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:407)
  at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:376)
  at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:95)
  at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:74)
  at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:75)
  at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:299)
  at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:266)
  at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:230)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
  at java.lang.Thread.run(Thread.java:818)
  at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:446)

Sie können sich den Screenshot ansehen, der zeigt, dass Bilder heruntergeladen und auf dem Gerät gespeichert wurden.

enter image description here

0
vinay 18 Apr. 2018 im 11:36

4 Antworten

Beste Antwort

Es ist schon eine Weile her, dass ich diese Frage gestellt habe, nachdem ich alle bereitgestellten Lösungen durchgesehen habe. Ich veröffentliche eine Lösung, die für mich funktioniert hat.

Zuerst wurde eine einzelne Gleitinstanz erstellt und in der gesamten Anwendung verwendet

mainFragment.getmGlide().with(mainFragment.getMcurrentContext())

Als nächstes wurden die Anforderungsoptionen hinzugefügt, um die Höhe und Breite des Bildes einzuschränken, wodurch die Speichernutzung erheblich reduziert wurde.

RequestOptions requestOptions = new RequestOptions();
    requestOptions.dontAnimate();
    requestOptions.diskCacheStrategy(DiskCacheStrategy.RESOURCE);
    requestOptions.timeout(10000);
    requestOptions.override(2000,2000);
    requestOptions.fitCenter();
    requestOptions.format(DecodeFormat.PREFER_RGB_565);
mainFragment.getmGlide().with(mainFragment.getMcurrentContext())
 .asBitmap()
 .load(rogImage)
 .apply(requestOptions)
 .listener(new RequestListener<Drawable>() {
        @Override
        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
            ProgressBarHandler.unloadProgressScreen(getActivity());
            return false;
        }
    })
    .into(new SimpleTarget<Drawable>() {
        @Override
        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
            tempImageView.setImageDrawable(resource)
        }

    });

Vielen Dank für Ihre vorgeschlagene Lösung.

0
vinay 18 Feb. 2019 im 09:45

Fügen Sie dies im Manifest hinzu

  android:largeHeap="true"

Fügen Sie auch hinzu, dies ist app.gradle

 dexOptions {// Prevent OutOfMemory with MultiDex during the build phase
        javaMaxHeapSize "4g"
    }
3
Jyot 18 Apr. 2018 im 08:43

Versuchen Sie es unten

Glide.with(context)
    .load(imgUrl)
    .thumbnail(0.1f)
    .into(imageView);

Überprüfen Sie die Referenz

1
sm_ 18 Apr. 2018 im 11:07

210 MB Bild (o.O.) ist zu groß, um es in den Speicher zu laden! Wenn Ihre Bildgröße wirklich 210 MB beträgt, ist es meiner Meinung nach am besten, das Bild als Stream auf die Festplatte herunterzuladen, indem Sie httpConnection oder Bibliotheken wie okhttp verwenden und dann die verkleinerte Version Ihres Bildes in den Speicher laden und dem Benutzer anzeigen!

Informationen zum effizienten Laden großer Bitmaps finden Sie unter dem Link für Entwickler:

https://developer.android.com/topic/performance/graphics/load-bitmap.html#load-bitmap

Verwenden Sie diese Bibliothek, wenn Sie dem Benutzer das gesamte Bild anzeigen möchten:

https://github.com/davemorrissey/subsampling-scale-image-view

1
Amir Hossein Mirzaei 18 Apr. 2018 im 11:16