Code Monkey home page Code Monkey logo

coil's People

Contributors

afigaliyev avatar chao2zhang avatar colinrtwhite avatar cortinico avatar dependabot[bot] avatar goooler avatar jawnnypoo avatar khang-nt avatar kimhc999 avatar kmshack avatar kuramu1108 avatar mario avatar matteinn avatar mohamed-khaled-hsn avatar mohamedrejeb avatar nuhkoca avatar pavneet-sing avatar r12rus avatar renovate[bot] avatar revonateb0t avatar rharter avatar romainguy avatar sagar-viradiya avatar shenghaiyang avatar vitusortner avatar whitescent avatar ychescale9 avatar yschimke avatar zacsweers avatar zhanghai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coil's Issues

Coil does not upscale resources

Describe the bug
When I download a resource from URL and its size is smaller than the requested size in the GetRequestBuilder, result is not upscaled. On the contrary, when I set a smaller size inside my GetRequestBuilder, the resource is correctly downscaled.

To Reproduce
Download this image using Coil.get(url) { size(256, 256) }

Expected behavior
I would expect to have a resulting drawable of 256x256 instead of the 24x24 provided

Library version
0.6.1

Coil.get() throws IllegalArgumentException when converting SVG toBitmap

Latest version 0.7.0 crash when attempting to get SVG asset via Coil.get() and using Drawable .toBitmap() to convert it to a bitmap.

Usage:

    Coil.get(iconUrl)
        .toBitmap()

Stacktrace:

java.lang.IllegalArgumentException: width and height must be > 0
    at android.graphics.Bitmap.createBitmap(Bitmap.java:829)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:808)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:775)
    at androidx.core.graphics.drawable.DrawableKt.toBitmap(Drawable.kt:60)
    at androidx.core.graphics.drawable.DrawableKt.toBitmap$default(Drawable.kt:45)
...
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)

android.resource Uris that point to another package's resource ID fail to load

Describe the bug
imageView.load(uri) doesn't load image from android.resource:// uri.

To Reproduce

  1. Apply this patch to coil sample app.
  2. Run sample app
  3. Notice icon image is not loaded.
  4. To check expected result comment out detail.load(uri) and un-comment detail.setImageURI(uri)

Expected behavior
Image loaded from uri

Logs/Screenshots

Current Expected
Screenshot_1566084096 Screenshot_1566083962

Library version
0.6.1

tested on Android 10

Any best practises for RecyclerView?

Is your feature request related to a problem? Please describe.
I would like to know, how can I optimize Coil for proper work with RecyclerView. I am loading the whole device's gallery in it using Coil and it properly loads all images separately, but if I would scroll list there are animations drops. Maybe there is some kind of optimization for such situations?

Refresh picture flicker

memoryCachePolicy(CachePolicy.DISABLED) after loading the same picture will cause flicker, glide has dontAnimate() can solve, the coil?

Incompatible with JVM 1.8

If in build.gradle i have

compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
}

I'll get this error if i'll try to do imageView.load("url")

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option

Disk cache for custom Fetcher without the use of OkHttp

Is your feature request related to a problem? Please describe.
Implementing a custom fetcher seems to also require the implementation of disk cache.

Describe the solution you'd like
An interface to provide a bitmap and have it cached on disk, preventing unnecessary fetches.

Note
I apologize if I'm missing a simple solution.

ImageView with one of its dimensions set to wrap_content does not work

Describe the bug
Assume the following ImageView:

<ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter" />

If you try to load an image to it, Coil will not calculate the correct width (based on the ImageView's fixed height and the aspect ratio of the image being loaded), and the ImageView will end up with a 0 width.

Using size() solves this issue, but it is not ideal because it is not always possible to know beforehand the dimensions of the image being loaded.

To Reproduce
Load an image to an ImageView which has one fixed dimension, and one wrap_content dimension.
Sample project: CoilWrapContent.zip

Expected behavior
Coil should automatically calculate the dimension set to wrap_content based on the fixed dimension & the dimensions of the image being loaded.

For example: If I load a 400x200 (2:1 aspect ratio) image to an ImageView with android:layout_width="wrap_content" and android:layout_height="100dp", then Coil should automatically set the width to 200dp (perhaps this shouldn't apply to all scaleTypes).

Logs/Screenshots
Layout Inspector screenshot showing the ImageView having its width set to 0:
image

Library version
0.6.0

Crash when loading image into AppCompatImageView

I attempted to migrate from Glide to Coil in my app. After switching to Coil, the app crashed in runtime as soon as an image was downloaded when it was being set to a androidx.appcompat.widget.AppCompatImageView descendant.
May be worth to note, that I'm using this ui library: https://github.com/stfalcon-studio/ChatKit
Could you help me understand what the issue is and if there are any possible workarounds?

Here's the stacktrace:
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps at android.graphics.BaseCanvas.onHwBitmapInSwMode(BaseCanvas.java:550) at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:557) at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:69) at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:127) at android.graphics.Canvas.drawBitmap(Canvas.java:1504) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545) at android.widget.ImageView.onDraw(ImageView.java:1360) at com.stfalcon.chatkit.utils.ShapeImageView.onDraw(ShapeImageView.java:70) at android.view.View.draw(View.java:20207) at android.view.View.buildDrawingCacheImpl(View.java:19478) at android.view.View.buildDrawingCache(View.java:19338) at android.view.View.draw(View.java:19927) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.updateDisplayListIfDirty(View.java:19073) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at androidx.recyclerview.widget.RecyclerView.drawChild(RecyclerView.java:5011) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.draw(View.java:20210) at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4410) at android.view.View.updateDisplayListIfDirty(View.java:19082) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:2023) at android.view.View.draw(View.java:20210) at android.view.View.updateDisplayListIfDirty(View.java:19082) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.draw(View.java:20210) at android.view.View.updateDisplayListIfDirty(View.java:19082) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.updateDisplayListIfDirty(View.java:19073) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.updateDisplayListIfDirty(View.java:19073) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.updateDisplayListIfDirty(View.java:19073) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.updateDisplayListIfDirty(View.java:19073) at android.view.View.draw(View.java:19935) at android.view.ViewGroup.drawChild(ViewGroup.java:4333) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112) at android.view.View.draw(View.java:20210) at com.android.internal.policy.DecorView.draw(DecorView.java:780) at android.view.View.updateDisplayListIfDirty(View.java:19082) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:801) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3311) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3115) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2484) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949) at android.view.Choreographer.doCallbacks(Choreographer.java:761) at android.view.Choreographer.doFrame(Choreographer.java:696) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Unable to Load Local / Regular Image

Hi, I', trying to load local image from drawable, but it's not displaying the image in my recycler view. But if I try view.ivAccount.setImageResource(account.image) the native code to display, then it works.
image

Please have a look into attached screenshots that are not working using your code.
no_image

Your Code Screenshot:
code

Unable to view images loaded in RecyclerView

Describe the bug
A clear and concise description of what the bug is.
When images are loaded with URLs in a RecyclerView, the RecyclerView is still blank. I believe this could be because after the image is retrieved, there is no call to remeasure/invalidate/notify the view.

To Reproduce
How can we reproduce this?

  1. Create a Single page application with a RecyclerView and a ViewHolder containing an ImageView.
  2. Load up an image into the ImageView
    Code snippet below:
    class Adapter(private val list: List<String>) : RecyclerView.Adapter<VH>() {

        override fun getItemCount(): Int = list.size
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH = VH(ImageView(parent.context))
        override fun onBindViewHolder(holder: VH, position: Int) {
            holder.imageView.load(list[position])
        }
    }

    class VH(val imageView: ImageView) : RecyclerView.ViewHolder(imageView)

Expected behavior
A clear and concise description of what you expected to happen.
I expect the Image to load up like in Glide and Picasso.
The only way i can get it to show up in a RecyclerView at the moment is if I set the height of the view to a non-zero value.

Logs/Screenshots
If applicable, add logs or screenshots to help explain your problem.
Screenshot_1565680640

Library version
0.6.0

Coil leaks Activity Context when an Activity with an ongoing request is destroyed

Describe the bug
Coil causes a memory leak when finish() is called on an Activity that has an ongoing request.

To Reproduce
Download & run the attached project:
CoilMemoryLeak.zip

ActivityA tries to load an "image" from a URL that takes 60 seconds to respond. If you click the "Go to Activity B" button during that time, then LeakCanary should detect retained objects (check the notification). This does not happen if the request has finished before going to ActivityB.

Expected behavior
Any references to the Activity should always be cleared when it is destroyed.

Logs/Screenshots

2019-08-12 14:51:11.619 8859-9256/com.example.coilmemoryleak D/LeakCanary: HeapAnalysisSuccess(heapDumpFile=/data/user/0/com.example.coilmemoryleak/files/leakcanary/2019-08-12_14-50-53_530.hprof, createdAtTimeMillis=1565610671616, analysisDurationMillis=14783, applicationLeaks=[ApplicationLeak(className=com.example.coilmemoryleak.ActivityA, leakTrace=
    ┬
    ├─ android.os.HandlerThread
    │    Leaking: NO (PathClassLoader↓ is not leaking)
    │    Thread name: 'LeakCanary-Heap-Dump'
    │    GC Root: Thread object
    │    ↓ thread HandlerThread.contextClassLoader
    ├─ dalvik.system.PathClassLoader
    │    Leaking: NO (Object[]↓ is not leaking and A ClassLoader is never leaking)
    │    ↓ PathClassLoader.runtimeInternalObjects
    ├─ java.lang.Object[]
    │    Leaking: NO (Coil↓ is not leaking)
    │    ↓ array Object[].[870]
    ├─ coil.Coil
    │    Leaking: NO (a class is never leaking)
    │    ↓ static Coil.imageLoader
    │                  ~~~~~~~~~~~
    ├─ coil.RealImageLoader
    │    Leaking: UNKNOWN
    │    ↓ RealImageLoader.loaderScope
    │                      ~~~~~~~~~~~
    ├─ kotlinx.coroutines.internal.ContextScope
    │    Leaking: UNKNOWN
    │    ↓ ContextScope.coroutineContext
    │                   ~~~~~~~~~~~~~~~~
    ├─ kotlin.coroutines.CombinedContext
    │    Leaking: UNKNOWN
    │    ↓ CombinedContext.left
    │                      ~~~~
    ├─ kotlinx.coroutines.SupervisorJobImpl
    │    Leaking: UNKNOWN
    │    ↓ SupervisorJobImpl._state
    │                        ~~~~~~
    ├─ kotlinx.coroutines.NodeList
    │    Leaking: UNKNOWN
    │    ↓ NodeList._next
    │               ~~~~~
    ├─ kotlinx.coroutines.ChildHandleNode
    │    Leaking: UNKNOWN
    │    ↓ ChildHandleNode.childJob
    │                      ~~~~~~~~
    ├─ kotlinx.coroutines.StandaloneCoroutine
    │    Leaking: UNKNOWN
    │    ↓ StandaloneCoroutine._state
    │                          ~~~~~~
    ├─ kotlinx.coroutines.ChildHandleNode
    │    Leaking: UNKNOWN
    │    ↓ ChildHandleNode.childJob
    │                      ~~~~~~~~
    ├─ kotlinx.coroutines.UndispatchedCoroutine
    │    Leaking: UNKNOWN
    │    ↓ UndispatchedCoroutine.uCont
    │                            ~~~~~
    ├─ coil.RealImageLoader$load$job$1
    │    Leaking: UNKNOWN
    │    Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
    │    ↓ RealImageLoader$load$job$1.$request
    │                                 ~~~~~~~~
    ├─ coil.request.LoadRequest
    │    Leaking: UNKNOWN
    │    ↓ LoadRequest.context
    │                  ~~~~~~~
    ╰→ com.example.coilmemoryleak.ActivityA
    ​     Leaking: YES (Activity#mDestroyed is true and ObjectWatcher was watching this)
    ​     key = 0893b148-6f03-4932-ad48-e07e204abb86
    ​     watchDurationMillis = 336257
    ​     retainedDurationMillis = 331257
    , retainedHeapByteSize=69591)], libraryLeaks=[])

Library version
0.6.0

Unable to access `get` methods

Describe the bug
I am using io.coil-kt:coil-base because I want to take advantage of DI.

However, I am not sure how to use ImageVIew. There seems to be some IDE wired behavior where get methods are visible in code completion but missing in the actual code.

To Reproduce
How can we reproduce this?

import android.os.Bundle
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import coil.ImageLoader
import com.igorwojda.showcase.R
import com.igorwojda.showcase.base.presentation.activity.BaseActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : BaseActivity() {

    override val layoutResId = R.layout.activity_main

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val imageLoader = ImageLoader(this)
        
		CoroutineScope(Dispatchers.Main).launch {
            imageLoader.get("url")
        }
    }
}

Code completion seems to show all posibilitie overloads (inclusing ImageView extensions)
image

...but they can't be used 🤔
image

Expected behavior
Just load an image using the get method
imageLoader.get("url")

(ideally, ImageView instance will be injected - this is a simplified example)

Library version
e.g. 0.6.0

Image Sampling not working as shown in the README preview gif

Describe the bug
I tried to set up image sampling the way it is described in :

https://coil-kt.github.io/coil/getting_started/#image-sampling

but I don't see any low-res image loaded with a crossfade effect to the high-res image.

To Reproduce

imageView.load(image) {
    crossfade(true)
}

I am loading images in a RecyclerView.Adapter.

Expected behavior
A crossfade effect from low to the high res image.

Logs/Screenshots

Library version
e.g. 0.6.0

Crash app when loading GIF on Android 9.0

Describe the bug
Crash on Android 9.0 when loading GIF-image

To Reproduce

  1. Add io.coil-kt:coil-gif to dependencies
  2. Try to load this GIF-file:
    success
  3. Image will freeze at start frame
  4. After ~2 seconds crash will happened

Expected behavior
GIF picture will load and move

Logs/Screenshots

A/libc: Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 8197 (AnimatedImageTh), pid 8010 (app.package.name)

Usage:
Code screenshot
Image container:
Image view container
Tested on devices:

  • Nokia 6.1 (Android 9.0)
  • Honor 9 Lite (Android 9.0)

Library version
version 0.6.0

How to CustomTarget<Bitmap> Listener

Trying to implement Coil on my existing application where Glide already using.
Need to achieve this...

    val bitmapTarget = object : CustomTarget<Bitmap>(DeviceUtils.dpToPx(282), DeviceUtils.dpToPx(159)) {
        override fun onLoadCleared(placeholder: Drawable?) {

        }

        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
            if (activity != null && isAdded) {
                row.setImageBitmap(mContext, resource)
                arrayAdapter!!.notifyArrayItemRangeChanged(0, arrayAdapter!!.size())
            }
        }
    }
    GlideApp.with(mContext)
        .asBitmap()
        .load(thumbImage)
        .into(bitmapTarget)

Unable to view images loaded in RecyclerView

Describe the bug
When images are loaded with URLs in a RecyclerView, the RecyclerView is still blank. I believe this could be because after the image is retrieved, there is no call to remeasure/invalidate/notify the view.

To Reproduce
Create a Single page application with a RecyclerView and a ViewHolder containing an ImageView.
Load up an image into the ImageView
Code snippet below:

   class Adapter(private val urlList: List<String>) : RecyclerView.Adapter<VH>() {

        override fun getItemCount(): Int = urlList.size
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH = VH(ImageView(parent.context))
        override fun onBindViewHolder(holder: VH, position: Int) {
            holder.imageView.load(urlList[position])
        }
    }

    class VH(val imageView: ImageView) : RecyclerView.ViewHolder(imageView)

Expected behavior
I expect the Image to load up like in Glide and Picasso.
The only way i can get it to show up in a RecyclerView at the moment is if I set the height of the view to a non-zero value.

Logs/Screenshots
If applicable, add logs or screenshots to help explain your problem.
Screenshot_1565680640

Library version
0.6.0

Support animated-WebP for all API level

In our projects with minimal API 21,
we use fresco library to load an amount of animated-webp
(from local file in assets and also from url)

I can see there's a GifDecoder for gif decoding/loading for all API level.
Would Coil support a decoder like WebPDecoder prior to Android P?

RoundedCornersTransformation support individual corner radius setting

Is your feature request related to a problem? Please describe.
Currently the RoundedCornersTransformation only allows the setting of the radius for all corners, RoundedCornersTransformation(radius:Float). It would be nice to have the flexibility to specify the corners that I would to have the radius applied only.

Describe the solution you'd like
Example would be for the api to be like RoundedCornersTransformation(radius:Float, RoundedCornersTransformation.TOP_LEFT or RoundedCornersTransformation.TOP_RIGHT) using an IntDef to specify corners to apply the radius.

The IntDef list could be like

RoundedCornersTransformation.TOP_RIGHT
RoundedCornersTransformation.TOP_LEFT
RoundedCornersTransformation.BOTTOM_LEFT
RoundedCornersTransformation.BOTTOM_RIGHT
RoundedCornersTransformation.ALL

Add support for loading placeholder image from cache via URL

First up, congrats on shipping!

A feature request for consideration. Sometimes an app will show a list of small image thumbnails, which are clickable to open the image full screen. The thumbnails are physically small (in dimension and file size) so the list of thumbnails loads quickly. The full images (loaded from a different URL to the thumbnail) are much bigger, so might take a few seconds to load from the network.

Currently, Coil supports specifying a placeholder Drawable using the placeholder method. It would be good if that was extended to allow passing in the URL of the thumbnail, which presumably would still be in the memory cache because it was being displayed on the previous screen.

The desired effect would look like the image sampling mentioned on the docs website. So the low-res thumbnail would be shown until the full-res image has loaded. The API difference being the first low-res image has come from a different URL, rather than the same one.

I've used "URL" above to keep the wording simple, but I mean all the different "sources" in general that are parameters to the ImageLoader.load methods (String, Uri, HttpUrl, etc), or the loadAny method that uses a Mapper.

Creating default OkHttp Cache can trigger strict mode violation.

Describe the bug
See strict mode warning below.

To Reproduce
Use Image.load() from inside a RecyclerView.Adapter. I didn't see it happening when it's used from inside a Fragment.

Expected behavior
Dispatchers.IO should be used. It also wouldn't hurt to be able to pass a custom lifecycle (actually a different issue) as well.

Logs/Screenshots

2019-08-19 16:00:08.236 17277-17277/ D/StrictMode: StrictMode policy violation; ~duration=326 ms: android.os.strictmode.DiskReadViolation
        at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1504)
        at java.io.UnixFileSystem.checkAccess(UnixFileSystem.java:251)
        at java.io.File.exists(File.java:1152)
        at java.io.File.mkdirs(File.java:1714)
        at coil.util.Utils.getDefaultCacheDirectory(Utils.kt:33)
        at coil.ImageLoaderBuilder.buildDefaultOkHttpClient(ImageLoaderBuilder.kt:189)
        at coil.ImageLoaderBuilder.build(ImageLoaderBuilder.kt:182)
        at coil.Coil.buildDefaultImageLoader(Coil.kt:57)
        at coil.Coil.loader(Coil.kt:20)
...

Library version
0.6.1

Relax Java8 requirement

Is your feature request related to a problem? Please describe.
Pure-Kotlin Android projects don't have to care about Java8 compatibility and thus stick to Kotlin defaults (i.e. Java 1.6 bytecode compatibility).

   > Failed to transform artifact 'lifecycle-common-java8.jar (androidx.lifecycle:lifecycle-common-java8:2.0.0)' to match attributes {artifactType=android-dex, dexing-enable-desugaring=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
      > Execution failed for DexingNoClasspathTransform: /home/saschpe/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common-java8/2.0.0/52cb9efc663d8bebc82f8979a7da30938bd05611/lifecycle-common-java8-2.0.0.jar.

Currently, one has to add quite a bit of boilerplate with Gradle Kotlin DSL:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

android {
    compileOptions {
        setSourceCompatibility(1.8)
        setTargetCompatibility(1.8)
    }
}

tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "1.8" }

Describe the solution you'd like
Align with standard Kotlin and require only androidx.lifecycle:lifecycle-common:2.0.0 (and others) to increase compatibility.

Support for a regular suspending ImageView.load

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.

I'm not quite understanding why the implementation chose to go with a custom RequestDisposable over job or a pure suspending alternative. Normally, I delegate some network tasks in my RecyclerViews to my ViewHolders like so

abstract class CoroutineViewHolder(
    itemView: View,
    scope: CoroutineScope
) : RecyclerView.ViewHolder(itemView), CoroutineScope by scope {

    /**
     * This establishes a lifecycle for recycling of views for
     * coroutine aware ViewHolders. Cancel the work that's being
     * done if this view is recycled and no longer needed.
     */
    @CallSuper
    fun onRecycled() {
        this.cancel("${this}.onRecycled called")
    }
}

where onRecycled is a method I call from a similar coroutine adapter I've made.

abstract class CoroutineAdapter<T : CoroutineViewHolder>(scope: CoroutineScope) : RecyclerView.Adapter<T>(), CoroutineScope by scope  {

    @CallSuper
    override fun onViewRecycled(holder: T) {
        super.onViewRecycled(holder)
        holder.onRecycled()
    }
}

needing to be bound to use a RequestDisposable seems like reinventing the wheel to me. There's got to be something I'm missing for this design choice.

Describe the solution you'd like
If possible, a pure susending ImageView.load function would be great.

Additional context
Add any other context or screenshots about the feature request here.

Unit testing

Describe the bug
When an app makes use of Robolectric and tests fragments or activities which in turn use Coil to load images, the default image loader needs to be initialized manually (via CoilContentProvider). The canonical way to do this with Robolectric would be to put this in a @before method in a JUnit4 based unit test class or a custom Application instance:

Robolectric.setupContentProvider(CoilContentProvider::class.java)

This doesn't work though as CoilContentProvider is internal. So the most viable option is

Coil.setDefaultImageLoader(ImageLoader(ApplicationProvider.getApplicationContext()))

To Reproduce
Invoke a unit test for a fragment or activity using coil (e.g. with launchFragmentInContainer, the new way to test fragments).

Expected behavior
The usage of setDefaultImageLoader is a little hidden in the existing documentation. Ideally, a dedicated Testing page with a paragraph on Robolectric would be good (I'm willing to start writing it) and / or CoilContentProvider is marked as @VisibleForTesting.

Logs/Screenshots

java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
	at org.robolectric.android.internal.AndroidTestEnvironment.checkStateAfterTestFailure(AndroidTestEnvironment.java:470)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:548)
	at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
	at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
	at coil.util.CoilContentProvider$Companion.getContext$coil_default_release(CoilContentProvider.kt:17)
	at coil.Coil.buildDefaultImageLoader(Coil.kt:48)
	at coil.Coil.loader(Coil.kt:20)

Library version
0.7.0

Crossfade + placeholder + wrap_content can result in a streched image

Describe the bug
Loading an image with crossfade and a placeholder enabled can result in a stretched image if the ImageView uses wrap_content and the placeholder has a different aspect ratio than the image being loaded.

If the app goes to the background and then to the foreground again, the image appears correctly.

(the placeholder has to be larger than the ImageView for this to occur)

To Reproduce
Sample project: CoilPlaceholderAR.zip

Expected behavior
The loaded image should not appear stretched.

Logs/Screenshots
device-2019-08-16-143148-2

Library version
0.6.1 (manually compiled)

Loading files via URI string fails

Is your feature request related to a problem? Please describe.
ImageView.load("file:///data/user/0/foo/cache/1.jpg") fails with

 java.lang.IllegalArgumentException: Expected URL scheme 'http' or 'https' but was 'file'
        at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1328)

because it is directly handed down to OkHttp3.

Describe the solution you'd like
A check if the Uri starts with *file:// could map to load(file: File) instead.

Support loading Uri Strings

Is your feature request related to a problem? Please describe.
Currently load(String) must always be a valid URL, but we could support automatically switching between Uris and HttpUrls.

Describe the solution you'd like
This should load the file/asset Uri correctly:

imageView.load("file:///android_asset/starrynight.jpg")

Additional context
Glide and Picasso already handle this.

Previous discussion: #10

Unable to load local vector drawables

Describe the bug
I have recently switched from Glide to Coil as image loading library, but after having implemented Coil just some images are loaded, the ones that are loaded by URL, while vector drawables are not displayed at all, even though I'm trying to strictly follow the documentation

To Reproduce
Create a vector drawable, place it under /res/drawables, then

val icon = layout.find<ImageView>(R.id.status_icon)
icon.load(R.drawable.status_ok)

Expected behavior
The icon should be displayed correctly
Coil Version 0.6.1

RoundedCorners not work

holder.imageViewCover.scaleType = ImageView.ScaleType.CENTER_CROP
holder.imageViewCover.load(producList[position].cover_image) {
transformations(RoundedCornersTransformation(32f))
}

but the image is not rounded conner

Coil should automatically rotate images based on Exif information

Describe the bug
When images have rotation information embedded within their Exif information, Coil should use that to automatically rotate the image correctly.

This is something that other image libraries (Glide, Picasso) do already. Using the AndroidX ExifInterface library allows you to extract the orientation information from any Uri / InputStream.

To Reproduce
You can use this sample image.

Expected behavior
The image should be rotated correctly.

Logs/Screenshots
n/a

Library version
0.6.1

Disabling the Memory Cache crashes the app

Describe the bug
When set the availableMemoryPercentage to 0.0 it crashes the app in the LruCache

To Reproduce

Coil.setDefaultImageLoader {
   ImageLoaderBuilder(application)
       .availableMemoryPercentage(0.0)
       .build()
}

Expected behavior
Setting availableMemoryCache to 0 disables the cache not crashes.

Logs/Screenshots

java.lang.IllegalArgumentException: maxSize <= 0
        at androidx.collection.LruCache.<init>(LruCache.java:53)
        at coil.memory.MemoryCache$cache$1.<init>(MemoryCache.kt:24)
        at coil.memory.MemoryCache.<init>(MemoryCache.kt:24)
        at coil.RealImageLoader.<init>(RealImageLoader.kt:93)
        at coil.ImageLoaderBuilder.build(ImageLoaderBuilder.kt:177)

Library version
0.6.1

Strict mode: Untagged network socket

Describe the bug
The underlying network socket managed by OkHttp isn't tagged according to policy. Strict mode complains about it. While it's a longstanding OkHttp issue other libraries apply a fixed tag.

To Reproduce
Enable strict mode in an app's Application class during onCreate():

if (BuildConfig.DEBUG) {
    StrictMode.enableDefaults()
}

Expected behavior
A clear and concise description of what you expected to happen.

Logs/Screenshots

2019-08-19 16:00:08.151 17277-17363/foo D/StrictMode: StrictMode policy violation: android.os.strictmode.UntaggedSocketViolation: Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage
        at android.os.StrictMode.onUntaggedSocket(StrictMode.java:2023)
        at com.android.server.NetworkManagementSocketTagger.tag(NetworkManagementSocketTagger.java:82)
...
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:245)
...

Library version
0.6.1

Support loading images from AssetManager

Is your feature request related to a problem? Please describe.
There's a very specific type of Uri on Android in the form of file:///android_asset/your_asset.jpg which, despite its file:// prefix, cannot be opened with ContentResolver.openInputStream() but instead must be opened using AssetManager.

This is true for all Uris in the form of ContentResolver.SCHEME_FILE + ":///android_asset/".

Describe the solution you'd like
I'd like to be able to use:

imageView.load("file:///android_asset/starrynight.jpg")

And have it automatically use AssetManager. I'd also be fine with using the load(Uri) version, although that would be a difference from Picasso and Glide (see examples below).

Additional context
Assets are already supported by Picasso:

 Picasso.get().load("file:///android_asset/starrynight.png").into(imageView)

and Glide

Glide.with(this).load("file:///android_asset/starrynight.jpg").into(imageView)

TooManyRequestsException

Describe Bug
To ManyRequest Exception on scroll recyclerview

Reproduce
Create recyclerview with the adapter using image url and scrolling from top list to bottom list with repeatedly

Error Message

E/UncaughtException: android.net.ConnectivityManager$TooManyRequestsException
at android.net.ConnectivityManager.convertServiceException(ConnectivityManager.java:2888)
at android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:3061)
at android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:3366)
at android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:3348)
at coil.network.NetworkObserverStrategyApi21.start(NetworkObserverStrategy.kt:102)
at coil.network.NetworkObserver.(NetworkObserver.kt:27)
at coil.RealImageLoader.(RealImageLoader.kt:94)
at coil.ImageLoaderBuilder.build(ImageLoaderBuilder.kt:177)

and I use this code for load image url

val cacheDirectory = context.cacheDir
        val cacheSize:Long = 200
        val cache = Cache(cacheDirectory, cacheSize)
        val client = OkHttpClient.Builder().cache(cache).build()

        val imageLoader = ImageLoader(context) {
            availableMemoryPercentage(0.25)
            bitmapPoolPercentage(0.25)
            crossfade(true)
            placeholder(context.getDrawable(R.drawable.ic_picture_placeholder))
            allowRgb565(true)
            okHttpClient(client)

        }
        imageView?.load(uri, imageLoader) {
            memoryCachePolicy(CachePolicy.DISABLED)
            diskCachePolicy(CachePolicy.DISABLED)
        }

is it possible to use a signature like Glide did it before, and they reload image from cache first if the image already loaded before?

Support loading frame image from video

Is your feature request related to a problem? Please describe.

    1. The album list has pictures and videos, but the load(file) method cannot load the video cover.
    1. I have a need to show video sequence frames, but there is no better way now.

Describe the solution you'd like
Glide is very compatible with image and video files. Loading video sequence frames is also very convenient,such as:

Glide.with(frameView).load(videoPath).apply(RequestOptions.frameOf(video.time * 1000).centerCrop()).into(frameView)

Better log-ability

Is your feature request related to a problem? Please describe.
None of the various load methods allow to inspect error conditions, i.e. why an image load failed. At the moment it's next to a black box. Interestingly, there is no log output either.

Describe the solution you'd like
Probably the easiest solution is to let load() methods accept another lambda that is called in case of errors, i.e. onSuccess = (Exception) -> Unit = {}

Typo in the documentation

At the documentation it says minSdkVersion = 14 , but When I run the app, it says that it requires Android N , minSdkVersion = 24 to run

I changed the minSdkVersion in my gradle to 24 and the app is running

Setup a benchmark with Glide, Fresco, Picasso

Setup a benchmark (memory, time, library size) with Glide, Fresco, Picasso for common set of scenarios

Why?

  • for comparison
  • to identify bottlenecks
  • to keep track of performance changes as library evolves

Crossfade doesn't like JPGs

Describe the bug
When loading a local jpg from the file-system, crossfade(true) causes a crash

To Reproduce
Happens when using coil with CircleImageView (didn't test plain ImageView).

Expected behavior
No crash.

Logs/Screenshots

2019-08-20 13:38:57.430 19165-19165/foo W/System.err: java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.BaseCanvas.onHwBitmapInSwMode(BaseCanvas.java:550)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:557)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:69)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:127)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.Canvas.drawBitmap(Canvas.java:1504)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at coil.drawable.CrossfadeDrawable.draw(CrossfadeDrawable.kt:41)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at de.hdodenhof.circleimageview.CircleImageView.getBitmapFromDrawable(CircleImageView.java:318)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at de.hdodenhof.circleimageview.CircleImageView.initializeBitmap(CircleImageView.java:330)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at de.hdodenhof.circleimageview.CircleImageView.setImageDrawable(CircleImageView.java:263)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at coil.target.ImageViewTarget.setDrawable(ImageViewTarget.kt:62)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at coil.target.ImageViewTarget.onSuccess(ImageViewTarget.kt:22)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at coil.memory.PoolableTargetDelegate.success(TargetDelegate.kt:192)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at coil.RealImageLoader$execute$2$deferred$1.invokeSuspend(RealImageLoader.kt:219)
2019-08-20 13:38:57.430 19165-19165/foo W/System.err:     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at android.os.Handler.handleCallback(Handler.java:873)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at android.os.Looper.loop(Looper.java:193)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6898)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
2019-08-20 13:38:57.431 19165-19165/foo W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Library version
0.6.1

Enable native support for SVG format without boilerplate

Currently using Glide to load SVG images and the implementation is quite clunky in order to do so. See: https://stackoverflow.com/questions/35507893/does-glide-have-a-method-for-loading-both-png-and-svg

As a fresh new library hot off the presses, I'd like to see Coil gracefully (and optimally) handle these file formats without a ton of boilerplate.

EDIT: WebP is already supported, so this enhancement request is more about formats that require an external library for decoding (and a Decoder).

Thanks!

ImageView dimensions are incorrect in ConstraintLayout

Describe the bug
When dimensions of ImageView are computed in ConstraintLayout with a constraint width percent, the size of the image is incorrect.

To Reproduce
Project is available. Search for ImageView with cover id.
https://github.com/damienLh/entract-cinema-android/blob/coil/app/src/main/res/layout/fragment_details.xml
https://github.com/damienLh/entract-cinema-android/blob/coil/app/src/main/kotlin/com/cinema/entract/app/ui/details/DetailsFragment.kt

Expected behavior
ImageView dimensions set to correct width percent constraint. In this example third of the screen width.

Logs/Screenshots
Current behaviour:
Screenshot_1568215876

Expected behaviour (Glide):
Screenshot_1568220983

Library version
0.7.0

Add support for applying transformation placeholder/error drawables

Is your feature request related to a problem? Please describe.
Suppose an ImageView showing the user's avatar. The user's avatar is loaded with a placeholder and has the CircleCropTransformation transformation applied to it. The placeholder will not be round which may cause the app to not look right on places where the avatar is expected to always be a circle.

Describe the solution you'd like
It should be possible to apply tranformations to the placeholder/error drawable as well. This could either be something like transformationsPlaceholder(...) or enablePlaceholderTransformations(true).

Another option would be to provide an overload on placeholder that accepts a RequestDisposable as an argument (similar to how Glide does it). This would also solve #27.

GIF-image not displayed properly

Describe the bug
When displaying GIF images, previous frames are not deleted

To Reproduce

  1. Add io.coil-kt:coil-gif to dependencies
  2. Try to load this GIF-file:
    success
  3. GIF is loaded and animating but it's noticeable that the image layers remain and do not disappear (static screenshot of this behavior):
    2019_08_13_13_57_58~2

Reproduces on device LG V30+ (Android 8.0 Stock)

Expected behavior
Previous GIF images will disappear after changing the frame

Logs/Screenshots
Usage:
Code screenshot
Image container:
изображение

Library version
Version 0.6.0

OOM exception when creating software bitmaps out of SVGs

Latest version 0.7.0 while creating software bitmaps from SVG assets causing an OOM exception when loading SVGs in a recyclerview. Was able to reproduce this 100% of the time on memory constrained Nexus 5x device.

To reproduce, create a basic recyclerview that loads a unique SVG graphic from web, and start scrollin'.

java.lang.OutOfMemoryError: Failed to allocate a 16000012 byte allocation with 8363936 free bytes and 7MB until OOM
    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
    at android.graphics.Bitmap.nativeCreate(Native Method)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:831)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:808)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:775)
    at coil.bitmappool.RealBitmapPool.get(RealBitmapPool.kt:77)
    at coil.drawable.SvgDrawable.draw(SvgDrawable.kt:50)
    at android.widget.ImageView.onDraw(ImageView.java:1246)
    at android.view.View.draw(View.java:16184)
    at android.view.View.updateDisplayListIfDirty(View.java:15180)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1765)
    at android.view.View.draw(View.java:16187)
    at android.view.View.updateDisplayListIfDirty(View.java:15180)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at androidx.recyclerview.widget.RecyclerView.drawChild(RecyclerView.java:5018)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.draw(View.java:16187)
    at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4417)
    at android.view.View.updateDisplayListIfDirty(View.java:15180)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.draw(View.java:16187)
    at android.view.View.updateDisplayListIfDirty(View.java:15180)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1256)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at androidx.fragment.app.FragmentContainerView.drawChild(FragmentContainerView.java:144)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at androidx.fragment.app.FragmentContainerView.dispatchDraw(FragmentContainerView.java:133)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1765)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.updateDisplayListIfDirty(View.java:15175)
    at android.view.View.draw(View.java:15954)
    at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
    at android.view.View.draw(View.java:16187)
	at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.jav

Access tokens in request headers

Is your feature request related to a problem? Please describe.
Thanks for this awesome library! I am trying it out in a project currently.
However, I am sending access tokens when loading the images.

Glide.with(context)
    .load(GlideUrl(imageUrl, LazyHeaders.Builder().addHeader(AUTHORIZATION, accessToken).build()))
    .into(imageView)

I looked around in the docs but couldn't find anything related to sending tokens in request headers.

Describe the solution you'd like
It would be great to have something like this:
imageView.load(imageUrl).header(AUTHORIZATION, accessToken)

Use placeholderRes/errorRes if url is null

It would be cool if passing null url would use placeholder drawable or error drawable if set. Right now it defeats the purpose of fluent api when you have to do something like:

if (imageUrl != null) { it.load(imageUrl) { placeholder(placeholderRes) } } else { it.setImageResource(placeholderRes) }

Forcing JVM target 1.8 causes incompatibility with Android SDK < 24

Describe the bug
Since Coil uses JVM target 1.8, this must be used in the application project as well. However, setting that target JVM can cause the Kotlin compiler to generate byte code that incompatible with Android SDK versions less than 24. See https://youtrack.jetbrains.com/issue/KT-19968.

To Reproduce
Use code similar to the code in the linked Kotlin issue. Try to run on a device with SDK version < 24.

Expected behavior
No hashCode related errors.

Logs/Screenshots

java.lang.NoSuchMethodError: No static method hashCode(J)I in class Ljava/lang/Long; or its super classes (declaration of 'java.lang.Long' appears in /system/framework/core-libart.jar)

Library version
0.6.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.