-
Notifications
You must be signed in to change notification settings - Fork 376
Advanced Usage
You can override global defaults by calling ImageService.Instance.Initialize
method in platform specific project. You can globally enable transparency channel, disable fade animation, specify own logger, timeouts and a lot more.
To use this method, you need to add a System.Net.Http
nuget package (PCL projects) or add a reference to System.Net.Http
(Android, iOS - Xamarin Studio: Edit references menu)
public static void Initialize(Configuration config)
Available configuration properties and their default values are here: Configuration.cs
By default FFImageLoading errors are logged to console. If you want to change that you can create a custom logger. Example:
public class CustomMiniLogger: IMiniLogger
{
public void Debug(string message)
{
}
public void Error(string errorMessage)
{
Insights.Report(ex);
}
public void Error(string errorMessage, Exception ex)
{
Insights.Report(ex, new Dictionary <string, string> { {"message", errorMessage} });
}
}
and instruct FFImageloading to use it in a platform specific project with:
ImageService.Instance.Initialize(logger: new CustomMiniLogger());
If you don't want to use the Retry() functionality but have your custom error handling/retry logic (for example: because you use Polly). Then you can use IntoAsync() instead of Into()
try {
// IntoAsync does not swallow exceptions so you should surround it with a try/catch
await ImageService.Instance.LoadUrl(urlToImage).IntoAsync(_imageView);
} catch (Exception ex) {
// do whatever you want...
}
If you want to stop pending loading requests. For example when your activity gets paused/resumed:
protected override void OnSleep()
{
base.OnSleep();
ImageService.Instance.SetExitTasksEarly(true);
}
protected override void OnResume()
{
base.OnResume();
ImageService.Instance.SetExitTasksEarly(false);
}
FFImageLoading image service preserves in heap memory of the device every image newly downloaded from url. In order to avoid application crash, you should reclaim memory in low memory situations.
Android
public override void OnTrimMemory([GeneratedEnum] TrimMemory level)
{
ImageService.Instance.InvalidateMemoryCache();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
base.OnTrimMemory(level);
}
For apps that use a lot of images, to have a all of them in memory you should use android:largeHeap="true" in AndroidManifest.xml. Memory usage fine tuning can be made by adding mono config parameters as stated here.
Be aware that when Java native code destroys ImageView, it does not call Dispose, so if you want to remove an image from memory cache, you have to override JavaFinalize in your custom ImageView control (or custom ImageViewAsync).
protected override void JavaFinalize()
{
SetImageDrawable(null);
SetImageBitmap(null);
ImageService.Instance.InvalidateCacheEntryAsync(this.DataLocationUri, FFImageLoading.Cache.CacheType.Memory);
base.JavaFinalize();
}
A single item can be removed from cache by awaiting:
await ImageService.Instance.InvalidateCacheEntryAsync(string key, CacheType cacheType, bool removeSimilar=false);
Removes image with given key from specified caches (Memory
, Disk
, All
).
If removeSimilar
is false then it will only remove this exact key. If a similar transformed image exists it will not be removed.
Otherwise, when removeSimilar
is true, even the transformed image will be removed from cache.
All caches can be cleared by awaiting:
await ImageService.Instance.InvalidateCacheAsync(CacheType cacheType);
Or, for memory cache only:
ImageService.Instance.InvalidateMemoryCache();
Or, for disk cache only:
await ImageService.Instance.InvalidateDiskCacheAsync();
If you want to load many images in a scrollable list view or horizontal list view and you have performance issues while you fling. In our app with more than 1000 items in an horizontal list view it was the case. To solve it we used:
_myListView.ScrollStateChanged += (object sender, ScrollStateChangedEventArgs scrollArgs) => {
switch (scrollArgs.ScrollState)
{
case ScrollState.Fling:
ImageService.Instance.SetPauseWork(true); // all image loading requests will be silently canceled
break;
case ScrollState.Idle:
ImageService.Instance.SetPauseWork(false); // loading requests are allowed again
// Here you should have your custom method that forces redrawing visible list items
_myListView.ForcePdfThumbnailsRedraw();
break;
}
};
Need to add custom listener for scroll event:
myRecyclerView.AddOnScrollListener(new CustomScrollListener());
class CustomScrollListener : RecyclerView.OnScrollListener
{
public override void OnScrollStateChanged(RecyclerView recyclerView, int newState)
{
base.OnScrollStateChanged(recyclerView, newState);
switch (newState)
{
case RecyclerView.ScrollStateDragging:
ImageService.Instance.SetPauseWork(true);
break;
case RecyclerView.ScrollStateIdle:
ImageService.Instance.SetPauseWork(false);
break;
}
}
}
Customizing the loading logic is very easy: inherit from ImageLoaderTask, put your own logic, and then pass the instance to ImageService: ImageService.Instance.LoadImage(customImageTask)
.