Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

sixty-two。 ImageLoader source code-process analysis

2025-02-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/03 Report--

one。 An introduction to ImageLoader Android library # 1 on GitHub. UIL aims to provide a powerful, flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.

According to the comments above on Github, ImageLoader is a powerful, flexible, highly customizable image loading and caching framework that has been displayed. It provides a large number of configurable options to control the loading and caching progress of images.

1.1 Github source code address

Https://github.com/nostra13/Android-Universal-Image-Loader

1.2 main classes and their functions introduce the main operator classes of the class name meaning ImageLoaderImageLoader, such as initialization, request to load pictures. ImageLoaderEngineImageLoader's engine, which contains several executor thread pools, can perform a variety of tasks, and some Executor can be configured in configuration. ImageViewAware input image control ImageView wrapper, weak reference to ImageView (to prevent memory leakage), encapsulate some methods, can be more convenient to operate ImageView, such as getting width and height, setting picture display and so on. Parameters when DisplayImageOptions requests to display pictures, such as default images, failed images, whether to use memory cache, and so on. For example, onLoadingStarted,onLoadingCompleteMemoryCacheMemoryCache is an interface for image memory caching, including a variety of implementation mechanisms, such as Lru, FIFO, LargestLimited and other DiskCache image disk cache interfaces, including a variety of cache naming algorithms. For example, when a picture is not found in memory in ImageLoadingInfo, such as md5,hashcode, and you are ready to look for it elsewhere. In order to facilitate the operation of encapsulated objects, such as picture uri,memorykey, imageLoadinglistener,progressListener, loadFromUriLockLoadedFrom enumeration types, indicate where the picture is obtained, including three types of NETWORK (network), DISC_CACHE (disk, SD card), MEMORY_CACHE (memory) ImageLoaderConfiguration very important objects, initialized in Application, including MemoryCache,DiskCache,ImageDownloader,ImageDecoder and other ImageDownloader image download interfaces, some implementation subclasses, such as BaseImageDownloader,SlowNetworkImageDownloader,NetworkDeniedImageDownloaderBaseImageDownloader basic picture download class Support network, assets, content, drawable and other pictures to get pictures on the SlowNetworkImageDownloader bottom network speed to obtain BitmapDisplayer picture display abstract classes, including a variety of picture display effects, such as the most common display pictures, rounded picture display and other 1.3 code packages and their meanings

Package names are used for the algorithm implementation of com.nostra13.universalimageloader.cache.disc disk cache naming and storage, such as md5 and hashcode names, and the implementation classes of com.nostra13.universalimageloader.cache.memory memory cache algorithms such as time storage, including the core code of com.nostra13.universalimageloader.coreImageLoader and main workflow classes such as first-in-first-out, Lru and so on. Com.nostra13.universalimageloader.core.assist auxiliary class, com.nostra13.universalimageloader.core.decode decoding, such as decoding from disk files to Bitmapcom.nostra13.universalimageloader.core.display picture display effect class, such as rounded corner, fade effect and other com.nostra13.universalimageloader.core.download picture download class, support network download picture, file read picture, assets picture, drawable, already contentProvider read picture com.nostra13.universalimageloader.core.imageawareImageView package, provide convenient operation to ImageView For example, to obtain ImageView height and width, whether to be recycled and other com.nostra13.universalimageloader.core.listener listeners, including image loading listening, loading progress monitoring, list sliding listening, the ability of com.nostra13.universalimageloader.core.process to release to the caller to process images. After obtaining the images, before displaying them, the callers can set this listener to process images, such as cutting images. Com.nostra13.universalimageloader.utils tool Class 4 Picture load sequence Diagram

two。 Easy to use

Https://www.cnblogs.com/yimi-yangguang/p/5715350.html

2.1 Applicationpublic class MyApplication extends Application {@ Override public void onCreate () {super.onCreate () ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder (this) .extracyCacheExtraOptions (480,800) / / default = device screen. Default is screen width and height dimensions Maximum width and height of memory cache .diskCacheExtraOptions (480,800, null) / / maximum width and height of disk cache Thread priority (Thread.NORM_PRIORITY-2) / / default / / thread priority is not limited by default. DenyCacheImageMultipleSizesInMemory () / blocks multi-size caching in memory. ConfiguyCacheSize (2 * 1024 * 1024) / configure cache size .cache percentage .diskCacheSizePercentage (13) / default / / (50 * 1024 * 1024) / / disk cache size Only valid with default cache .diskCacheFileCount (100) / / number of disk cache files, only valid with default cache .writeDebugLogs () / / print debug log .build () ImageLoader.getInstance () .init (config); / / initialization}} 2.2 load picture public class MainActivity extends AppCompatActivity {@ Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); ImageView imageView = findViewById (R.id.img_test); ImageLoader imageLoader = ImageLoader.getInstance () DisplayImageOptions options = new DisplayImageOptions.Builder () .showImageOnLoading (R.drawable.ic_launcher_background) / / resource or drawable. ShowImageForEmptyUri (R.drawable.ic_launcher_background) / / resource or drawable. ShowImageOnFail (R.drawable.ic_launcher_background) / / resource or drawable. ViewViewBeforeloading (false) / / default. DelayBeforeLoading (1000) .postProcessor (new BitmapProcessor () {@ Override public Bitmap process (Bitmap bitmap) {Log.d ("sandy") "process bitmap...") Return bitmap }}) .showImageOnLoading (R.drawable.ic_launcher_foreground) .cacheInMemory (false) / / default .cacheOnDisk (false) / / default .considerExifParams (false) / / default .imageScaleType (ImageScaleType.IN_SAMPLE_POWER_OF_2) / / default .bitmapConfig (Bitmap.Config.ARGB_8888) / / default .build () ImageLoader.displayImage ("http://img3.imgtn.bdimg.com/it/u=2200166214,500725521&fm=27&gp=0.jpg", imageView, options, new ImageLoadingListener () {@ Override public void onLoadingStarted (String imageUri, View view) {Log.d (" sandy "," onLoadingStarted imageUri: "+ imageUri) } @ Override public void onLoadingFailed (String imageUri, View view, FailReason failReason) {Log.d ("sandy", "onLoadingFailed imageUri:" + imageUri + "failReason:" + failReason) } @ Override public void onLoadingComplete (String imageUri, View view, Bitmap loadedImage) {Log.d ("sandy", "onLoadingComplete imageUri:" + imageUri) } @ Override public void onLoadingCancelled (String imageUri, View view) {Log.d ("sandy", "onLoadingCancelled imageUri:" + imageUri) }, new ImageLoadingProgressListener () {@ Override public void onProgressUpdate (String imageUri, View view, int current, int total) {Log.d ("sandy", "onProgressUpdate current:" + current + "total:" + total);}});}}. Process Analysis-initialization

According to the above usage, to analyze the source code of ImageLoader, first look at the ImageLoader code in the onCreate of Application.

Initialize ImageLoaderConfigurationImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder (this) .excepyCacheExtraOptions (480,800) / / default = device screen. Default is screen width and height dimensions. Maximum width and height of memory cache .diskCacheExtraOptions (480,800, null) / / maximum width and height of disk cache Thread priority (Thread.NORM_PRIORITY-2) / / default / / thread priority is not limited by default. DenyCacheImageMultipleSizesInMemory () / blocks multi-size caching in memory. ConfiguyCacheSize (2 * 1024 * 1024) / configure cache size .cache percentage .diskCacheSizePercentage (13) / default / / (50 * 1024 * 1024) / / disk cache size Only valid with default cache .diskCacheFileCount (100) / / number of disk cache files, only valid with default cache .writeDebugLogs () / / print debug log .build ()

This is a typical constructor pattern, which is generally suitable for scenarios with more attributes.

After setting the various properties, take a look at the build method.

3.1.1 build/** Builds configured {@ link ImageLoaderConfiguration} object * / public ImageLoaderConfiguration build () {initEmptyFieldsWithDefaultValues (); return new ImageLoaderConfiguration (this);}

InitEmptyFieldsWithDefaultValues is called first, and if the user does not set some properties, the default values are initialized for them.

Private void initEmptyFieldsWithDefaultValues () {if (taskExecutor = = null) {taskExecutor = DefaultConfigurationFactory .createExecutor (threadPoolSize, threadPriority, tasksProcessingType);} else {customExecutor = true;} if (taskExecutorForCachedImages = = null) {taskExecutorForCachedImages = DefaultConfigurationFactory .createExecutor (threadPoolSize, threadPriority, tasksProcessingType) } else {customExecutorForCachedImages = true;} if (diskCache = = null) {if (diskCacheFileNameGenerator = = null) {diskCacheFileNameGenerator = DefaultConfigurationFactory.createFileNameGenerator ();} diskCache = DefaultConfigurationFactory .createDiskCache (context, diskCacheFileNameGenerator, diskCacheSize, diskCacheFileCount) } if (memoryCache = = null) {memoryCache = DefaultConfigurationFactory.createMemoryCache (context, memoryCacheSize);} if (denyCacheImageMultipleSizesInMemory) {memoryCache = new FuzzyKeyMemoryCache (memoryCache, MemoryCacheUtils.createFuzzyKeyComparator ());} if (downloader = = null) {downloader = DefaultConfigurationFactory.createImageDownloader (context) } if (decoder = = null) {decoder = DefaultConfigurationFactory.createImageDecoder (writeLogs);} if (defaultDisplayImageOptions = = null) {defaultDisplayImageOptions = DisplayImageOptions.createSimple ();}}

Finally, the build method can produce an ImageLoaderConfiguration object.

Return new ImageLoaderConfiguration (this)

Once you have the configuration object ImageLoaderConfiguration, you will then use it to initialize ImageLoader

ImageLoader.getInstance () .init (config); / / initialize

To continue the analysis, first take a look at ImageLoader.getInstance ()

3.2 ImageLoader.getInstance () ImageLoader imageLoader = ImageLoader.getInstance ()

Continue to look at the ImageLoader.getInstance () method

3.2.1 ImageLoader.getInstance/** Returns singleton class instance * / public static ImageLoader getInstance () {if (instance = = null) {synchronized (ImageLoader.class) {if (instance = = null) {instance = new ImageLoader ();} return instance;}

GetInstance can be seen as a singleton mode with efficiency optimization (two layers of if judgment, the first layer can filter most of the access, thus reducing the number of times to enter the synchronized lock).

3. 3 ImageLoader.init (config) / * * Initializes ImageLoader instance with configuration. * If configurations was set before ({@ link # isInited ()} = = true) then this method does nothing. * To force initialization with new configuration you should {@ linkplain # destroy () destroy ImageLoader} at first. * * @ param configuration {@ linkplain ImageLoaderConfiguration ImageLoader configuration} * @ throws IllegalArgumentException if configuration parameter is null * / public synchronized void init (ImageLoaderConfiguration configuration) {if (configuration = = null) {throw new IllegalArgumentException (ERROR_INIT_CONFIG_WITH_NULL);} if (this.configuration = = null) {L.d (LOG_INIT_CONFIG); engine = new ImageLoaderEngine (configuration) This.configuration = configuration;} else {L.W (WARNING_RE_INIT_CONFIG);}}

According to the annotation, we initialize the ImageLoader with the incoming configuration object, and if the configuration has been set (isInit=true) before, nothing will happen.

If you want to replace the previous configuration object with the current configuration, you need to call the ImageLoader.destory () method to destroy it first.

If something is normal, an ImageLoaderEngine object is generated.

3.3.1 ImageLoaderEngineprivate Executor taskExecutor;private Executor taskExecutorForCachedImages;private Executor taskDistributor;ImageLoaderEngine (ImageLoaderConfiguration configuration) {this.configuration = configuration; taskExecutor = configuration.taskExecutor; taskExecutorForCachedImages = configuration.taskExecutorForCachedImages; taskDistributor = DefaultConfigurationFactory.createTaskDistributor ();}

ImageLoaderEngine saves the incoming configuration and then contains several Executor to perform various asynchronous tasks, so it is called Engine, the engine.

Among them, taskExecutor and taskExecutorForCachedImages are transmitted from configuration, in other words, we can configure them in configuration, and then we also create a taskDistributor Executor.

In this way, the initialization process in Application has been analyzed for a long time, so let's see how to use ImageLoader in Activity.

four。 Process Analysis-load Picture

First, continue to post a piece of code requesting to load the image, which is in the onCreate of Activity.

First

First of all, set the layout file findViewById to find the ImageView control that you want to display the image to initialize the display configuration, of course, or not, ImageLoader can use the default. Call the imageLoader.displayImage method to request to load the image, which can have the image address, image control, display configuration parameters, listener to load the image, and load progress listener. Protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); ImageView imageView = findViewById (R.id.img_test); ImageLoader imageLoader = ImageLoader.getInstance () DisplayImageOptions options = new DisplayImageOptions.Builder () .showImageOnLoading (R.drawable.ic_launcher_background) / / resource or drawable .showImageForEmptyUri (R.drawable.ic_launcher_background) / / resource or drawable .showImageOnFail (R.drawable.ic_launcher_background) / / resource or drawable .displaying ViewBeforeLoading (false) / / Default .delayBeforeLoading (1000) .postProcessor (new BitmapProcessor () {@ Override public Bitmap process (Bitmap bitmap) {Log.d ("sandy") "process bitmap...") Return bitmap }}) .showImageOnLoading (R.drawable.ic_launcher_foreground) / / .displayer (new RoundedBitmapDisplayer (5)) .cacheInMemory (false) / / default .cacheOnDisk (false) / / default .considerExifParams ( False) / / default .imageScaleType (ImageScaleType.IN_SAMPLE_POWER_OF_2) / / default .bitmapConfig (Bitmap.Config.ARGB_8888) / / default .build () ImageLoader.displayImage ("http://img3.imgtn.bdimg.com/it/u=2200166214,500725521&fm=27&gp=0.jpg", imageView, options, new ImageLoadingListener () {@ Override public void onLoadingStarted (String imageUri, View view) {Log.d (" sandy "," onLoadingStarted imageUri: "+ imageUri) } @ Override public void onLoadingFailed (String imageUri, View view, FailReason failReason) {Log.d ("sandy", "onLoadingFailed imageUri:" + imageUri + "failReason:" + failReason) } @ Override public void onLoadingComplete (String imageUri, View view, Bitmap loadedImage) {Log.d ("sandy", "onLoadingComplete imageUri:" + imageUri) } @ Override public void onLoadingCancelled (String imageUri, View view) {Log.d ("sandy", "onLoadingCancelled imageUri:" + imageUri) }}, new ImageLoadingProgressListener () {@ Override public void onProgressUpdate (String imageUri, View view, int current, int total) {Log.d ("sandy", "onProgressUpdate current:" + current + "total:" + total) });}

DisplayImageOptions image display parameters, you can not specify, you can also specify some display parameters, such as default image (displayed before the network image is loaded), failed image loading, whether to load from memory, these later analysis, does not involve the analysis of the process.

So move on to the ImageLoader.displayImage (xxx) method

4.1 ImageLoader.displayImagepublic void displayImage (String uri, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {displayImage (uri, new ImageViewAware (imageView), options, listener, progressListener);} public void displayImage (String uri, ImageAware imageAware, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {displayImage (uri, imageAware, options, null, listener, progressListener) } public void displayImage (String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {checkConfiguration (); if (imageAware = = null) {throw new IllegalArgumentException (ERROR_WRONG_ARGUMENTS);} if (listener = = null) {listener = defaultListener;} if (options = = null) {options = configuration.defaultDisplayImageOptions } if (TextUtils.isEmpty (uri)) {engine.cancelDisplayTaskFor (imageAware); listener.onLoadingStarted (uri, imageAware.getWrappedView ()); if (options.shouldShowImageForEmptyUri ()) {imageAware.setImageDrawable (options.getImageForEmptyUri (configuration.resources));} else {imageAware.setImageDrawable (null) } listener.onLoadingComplete (uri, imageAware.getWrappedView (), null); return;} if (targetSize = = null) {targetSize = ImageSizeUtils.defineTargetSizeForView (imageAware, configuration.getMaxImageSize ());} String memoryCacheKey = MemoryCacheUtils.generateKey (uri, targetSize); engine.prepareDisplayTaskFor (imageAware, memoryCacheKey); listener.onLoadingStarted (uri, imageAware.getWrappedView ()) Bitmap bmp = configuration.memoryCache.get (memoryCacheKey); if (bmp! = null & &! bmp.isRecycled ()) {L.D (LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey); if (options.shouldPostProcess ()) {ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo (uri, imageAware, targetSize, memoryCacheKey, options, listener, progressListener, engine.getLockForUri (uri)) ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask (engine, bmp, imageLoadingInfo, defineHandler (options)); if (options.isSyncLoading ()) {displayTask.run ();} else {engine.submit (displayTask) }} else {options.getDisplayer (). Display (bmp, imageAware, LoadedFrom.MEMORY_CACHE); listener.onLoadingComplete (uri, imageAware.getWrappedView (), bmp);}} else {if (options.shouldShowImageOnLoading ()) {imageAware.setImageDrawable (options.getImageOnLoading (configuration.resources)) } else if (options.isResetViewBeforeLoading ()) {imageAware.setImageDrawable (null);} ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo (uri, imageAware, targetSize, memoryCacheKey, options, listener, progressListener, engine.getLockForUri (uri)); LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask (engine, imageLoadingInfo, defineHandler (options)) If (options.isSyncLoading ()) {displayTask.run ();} else {engine.submit (displayTask);}} 4.2 ImageViewAware

In displayImage, the ImageView object is used to initialize an ImageViewAware object.

New ImageViewAware (imageView)

The inheritance relationship of ImageViewAware is as follows:

It mainly makes a weak reference to View, which can access some properties of the incoming ImageView, such as height width, setting to display pictures, and so on.

Protected Reference viewRef

The reason for creating an ImageViewAware is that ImageLoader wants to make it easy to manipulate the incoming ImageView object.

Let's take a look at the specific contents of displayImage (xx).

4.3 displayImage condition judgment public void displayImage (String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {checkConfiguration (); if (imageAware = = null) {throw new IllegalArgumentException (ERROR_WRONG_ARGUMENTS);} if (listener = = null) {listener = defaultListener;} if (options = null) {options = configuration.defaultDisplayImageOptions }...} private void checkConfiguration () {if (configuration = = null) {throw new IllegalStateException (ERROR_NOT_INIT);}}

The configuration,checkConfiguration is checked first, and if configuration==null, an error is reported. That is, if the ImageLoader.init () we mentioned earlier is not called, the initialization is as follows.

Public synchronized void init (ImageLoaderConfiguration configuration) {if (configuration = = null) {throw new IllegalArgumentException (ERROR_INIT_CONFIG_WITH_NULL);} if (this.configuration = = null) {L.D (LOG_INIT_CONFIG); engine = new ImageLoaderEngine (configuration); this.configuration = configuration;} else {L.w (WARNING_RE_INIT_CONFIG) }}

Then whether imageAware is null, if null, then the error is reported.

Then check whether listener, options is null, and if it is null, set it to the default value.

Continue to look at the code below

4.4 load empty picture address

If the image address passed in is null, then you will go to the following branch

If (TextUtils.isEmpty (uri)) {engine.cancelDisplayTaskFor (imageAware); listener.onLoadingStarted (uri, imageAware.getWrappedView ()); if (options.shouldShowImageForEmptyUri ()) {imageAware.setImageDrawable (options.getImageForEmptyUri (configuration.resources));} else {imageAware.setImageDrawable (null);} listener.onLoadingComplete (uri, imageAware.getWrappedView (), null); return;}

The above code does the following

Clear the engine to cancel the cache call listener.onLoadingStarted for this ImageAware. If you pass in listener, it will be called back at this time. Determine whether there is an empty picture in options, and if so, set ImageView to null if the picture is not set to empty. Then call listener.onLoadingComplete method 4.5 to initialize ImageSizeif (targetSize = = null) {targetSize = ImageSizeUtils.defineTargetSizeForView (imageAware, configuration.getMaxImageSize ());} public static ImageSize defineTargetSizeForView (ImageAware imageAware, ImageSize maxImageSize) {int width = imageAware.getWidth (); if (width

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report