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.
4 Antworten
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.
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"
}
Versuchen Sie es unten
Glide.with(context)
.load(imgUrl)
.thumbnail(0.1f)
.into(imageView);
Überprüfen Sie die Referenz
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
Neue Fragen
java
Java ist eine Programmiersprache auf hoher Ebene. Verwenden Sie dieses Tag, wenn Sie Probleme haben, die Sprache selbst zu verwenden oder zu verstehen. Dieses Tag wird selten alleine verwendet und wird am häufigsten in Verbindung mit [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] und [maven] verwendet.